From 297eb795b24ec31f6599f48bc8c3769557a7ec6f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 5 Aug 2018 12:32:42 +0800 Subject: Bump java lib versions to 13 Signed-off-by: Keith Packard --- altosuilib/AltosFlashUI.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'altosuilib/AltosFlashUI.java') diff --git a/altosuilib/AltosFlashUI.java b/altosuilib/AltosFlashUI.java index 802e8eb3..d6c7a16f 100644 --- a/altosuilib/AltosFlashUI.java +++ b/altosuilib/AltosFlashUI.java @@ -16,7 +16,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altosuilib_12; +package org.altusmetrum.altosuilib_13; import java.awt.*; import java.awt.event.*; @@ -24,7 +24,7 @@ import javax.swing.*; import javax.swing.filechooser.FileNameExtensionFilter; import java.io.*; import java.util.concurrent.*; -import org.altusmetrum.altoslib_12.*; +import org.altusmetrum.altoslib_13.*; public class AltosFlashUI extends AltosUIDialog -- cgit v1.2.3 From 75420fecbc76ab718661718ada249673e139a29d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 22 Aug 2018 00:56:25 -0700 Subject: altosuilib: Show a more useful message when the flash target device is unknown The flashing code uses the new symbol table to find information in the existing device; if they don't match at all, there won't be anything about the target device known. Tell the user this, rather than displaying mystic information (or crashing). Signed-off-by: Keith Packard --- altosuilib/AltosFlashUI.java | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) (limited to 'altosuilib/AltosFlashUI.java') diff --git a/altosuilib/AltosFlashUI.java b/altosuilib/AltosFlashUI.java index d6c7a16f..6dc80272 100644 --- a/altosuilib/AltosFlashUI.java +++ b/altosuilib/AltosFlashUI.java @@ -278,6 +278,12 @@ public class AltosFlashUI } boolean rom_config_matches (AltosRomconfig a, AltosRomconfig b) { + if (a == null || b == null) + return (a == null && b == null); + + if (!a.valid || !b.valid) + return false; + if (a.usb_id != null && b.usb_id != null && (a.usb_id.vid != b.usb_id.vid || a.usb_id.pid != b.usb_id.pid)) @@ -294,16 +300,27 @@ public class AltosFlashUI AltosRomconfig new_config; if (!rom_config_matches(existing_config, image_config)) { - int ret = JOptionPane.showConfirmDialog(this, - String.format("Device is %04x:%04x %s\nImage is %04x:%04x %s\nFlash anyways?", - existing_config.usb_id.vid, - existing_config.usb_id.pid, - existing_config.usb_product, - image_config.usb_id.vid, - image_config.usb_id.pid, - image_config.usb_product), - "Image doesn't match Device", - JOptionPane.YES_NO_OPTION); + int ret; + if (existing_config == null || !existing_config.valid) { + ret = JOptionPane.showConfirmDialog(this, + String.format("Cannot determine target device type\nImage is %04x:%04x %s\nFlash anyways?", + image_config.usb_id.vid, + image_config.usb_id.pid, + image_config.usb_product), + "Unknown Target Device", + JOptionPane.YES_NO_OPTION); + } else { + ret = JOptionPane.showConfirmDialog(this, + String.format("Device is %04x:%04x %s\nImage is %04x:%04x %s\nFlash anyways?", + existing_config.usb_id.vid, + existing_config.usb_id.pid, + existing_config.usb_product, + image_config.usb_id.vid, + image_config.usb_id.pid, + image_config.usb_product), + "Image doesn't match Device", + JOptionPane.YES_NO_OPTION); + } if (ret != JOptionPane.YES_OPTION) return false; } -- cgit v1.2.3 From 378ebab2e70917b4182cbd840a3fa66e4e42fd92 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 22 Aug 2018 17:42:13 -0700 Subject: altoslib: Use common constants for flash action messages Place messages in AltosFlashListener instead of using the same strings in three different places. Signed-off-by: Keith Packard --- altoslib/AltosFlash.java | 4 ++-- altoslib/AltosFlashListener.java | 4 ++++ altoslib/AltosSelfFlash.java | 4 ++-- altosuilib/AltosFlashUI.java | 4 ++-- 4 files changed, 10 insertions(+), 6 deletions(-) (limited to 'altosuilib/AltosFlashUI.java') diff --git a/altoslib/AltosFlash.java b/altoslib/AltosFlash.java index 520663b7..e6b05713 100644 --- a/altoslib/AltosFlash.java +++ b/altoslib/AltosFlash.java @@ -257,7 +257,7 @@ public class AltosFlash extends AltosProgrammer { int flash_addr = (int) image.address; int image_start = 0; - action("start", 0); + action(AltosFlashListener.flash_start, 0); action(0, image.data.length); while (remain > 0 && !aborted) { int this_time = remain; @@ -293,7 +293,7 @@ public class AltosFlash extends AltosProgrammer { action(image.data.length - remain, image.data.length); } if (!aborted) { - action("done", 100); + action(AltosFlashListener.flash_done, 100); if (debug != null) { debug.set_pc((int) image.address); debug.resume(); diff --git a/altoslib/AltosFlashListener.java b/altoslib/AltosFlashListener.java index f9eaf00f..120e7146 100644 --- a/altoslib/AltosFlashListener.java +++ b/altoslib/AltosFlashListener.java @@ -19,5 +19,9 @@ package org.altusmetrum.altoslib_13; public interface AltosFlashListener { + + public final static String flash_start = "start"; + public final static String flash_done = "done"; + public void position(String label, int percent); } diff --git a/altoslib/AltosSelfFlash.java b/altoslib/AltosSelfFlash.java index 75fc7946..20839ce4 100644 --- a/altoslib/AltosSelfFlash.java +++ b/altoslib/AltosSelfFlash.java @@ -101,7 +101,7 @@ public class AltosSelfFlash extends AltosProgrammer { long flash_addr = image.address; int image_start = 0; - action("start", 0); + action(AltosFlashListener.flash_start, 0); action(0, image.data.length); while (remain > 0 && !aborted) { int this_time = remain; @@ -129,7 +129,7 @@ public class AltosSelfFlash extends AltosProgrammer { action(image.data.length - remain, image.data.length); } if (!aborted) { - action("done", 100); + action(AltosFlashListener.flash_done, 100); } close(); } catch (IOException ie) { diff --git a/altosuilib/AltosFlashUI.java b/altosuilib/AltosFlashUI.java index 6dc80272..4d9c662c 100644 --- a/altosuilib/AltosFlashUI.java +++ b/altosuilib/AltosFlashUI.java @@ -116,10 +116,10 @@ public class AltosFlashUI JOptionPane.ERROR_MESSAGE); setVisible(false); dispose(); - } else if (cmd.equals("done")) { + } else if (cmd.equals(AltosFlashListener.flash_done)) { setVisible(false); dispose(); - } else if (cmd.equals("start")) { + } else if (cmd.equals(AltosFlashListener.flash_start)) { setVisible(true); } else { pbar.setValue(e.getID()); -- cgit v1.2.3 From 87ae17f888b745de71790d071846b96ab96e1529 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 22 Aug 2018 17:44:02 -0700 Subject: altosuilib: Provide dialog while waiting for flash target to re-appear On windows, switching to the boot loader can take a long time. Instead of timing out after a second, show a dialog and let the user cancel the operation if they get bored of waiting. Signed-off-by: Keith Packard --- altosuilib/AltosFlashUI.java | 254 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 222 insertions(+), 32 deletions(-) (limited to 'altosuilib/AltosFlashUI.java') diff --git a/altosuilib/AltosFlashUI.java b/altosuilib/AltosFlashUI.java index 4d9c662c..6c9cae52 100644 --- a/altosuilib/AltosFlashUI.java +++ b/altosuilib/AltosFlashUI.java @@ -346,7 +346,7 @@ public class AltosFlashUI device.toShortString()), "Device in use", JOptionPane.ERROR_MESSAGE); - } else if (e instanceof IOException) { + } else { JOptionPane.showMessageDialog(frame, e.getMessage(), file.toString(), @@ -429,45 +429,235 @@ public class AltosFlashUI flash_task flasher; - private boolean open_device() throws InterruptedException { - try { - link = new AltosSerial(device); - if (is_pair_programmed()) - return true; - if (link == null) - throw new IOException(String.format("%s: open failed", device.toShortString())); + class open_task implements Runnable { + AltosDevice device; + Thread t; + open_dialog dialog; - while (!link.is_loader()) { - link.to_loader(); + public void do_exception(final Exception e) { + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + try { dialog.open_exception(e); } catch (Exception ex) { } + } + }); + } - java.util.List devices = null; + public void do_success(final AltosLink link) { + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + try { dialog.open_success(link); } catch (Exception ex) { } + } + }); + } - for (int tries = 0; tries < 10; tries++) { - Thread.sleep(100); - devices = AltosUSBDevice.list(AltosLib.product_altusmetrum); - if (devices.size() != 0) - break; - } + public void do_failure() { + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + try { dialog.open_failure(); } catch (Exception ex) { } + } + }); + } + + public void do_cancel() { + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + try { dialog.open_cancel(); } catch (Exception ex) { } + } + }); + } + + public void run () { + try { + AltosLink link = null; + + for (;;) { + System.out.printf("Attempting to open %s\n", device.toShortString()); + + link = new AltosSerial(device); + + if (link == null) + throw new IOException(String.format("%s: open failed", + device.toShortString())); - if (devices.size() == 1) - device = devices.get(0); - else { - device = AltosDeviceUIDialog.show(frame, AltosLib.product_altusmetrum); - if (device == null) - return false; + /* See if the link is usable already */ + if (is_pair_programmed() || link.is_loader()) { + System.out.printf("Device ready for use\n"); + do_success(link); + return; + } + + java.util.List prev_devices = + AltosUSBDevice.list(AltosLib.product_altusmetrum); + + /* Nope, switch to loader and + * wait for it to re-appear + */ + + System.out.printf("Switch to loader\n"); + + link.to_loader(); + + /* This is a bit fragile, but + * I'm not sure what else to + * do other than ask the user. + * + * Search for a device which + * wasn't there before we + * asked the target to switch + * to loader mode + */ + + device = null; + for (;;) { + Thread.sleep(100); + java.util.List devices = + AltosUSBDevice.list(AltosLib.product_altusmetrum); + + for (AltosDevice d : devices) { + boolean matched = false; + System.out.printf("\tfound device %s\n", d.toShortString()); + for (AltosDevice p : prev_devices) + if (d.equals(p)) { + matched = true; + break; + } + if (!matched) { + System.out.printf("Identified new device %s\n", d.toShortString()); + device = d; + break; + } + } + if (device != null) + break; + } } - link = new AltosSerial(device); + } catch (AltosSerialInUseException ee) { + do_exception(ee); + } catch (FileNotFoundException fe) { + do_exception(fe); + } catch (IOException ie) { + do_exception (ie); + } catch (InterruptedException ie) { } - return true; - } catch (AltosSerialInUseException ee) { - exception(ee); - } catch (FileNotFoundException fe) { - exception(fe); - } catch (IOException ie) { - exception (ie); } - return false; + + public void cancel() { + t.interrupt(); + } + + public open_task(AltosDevice device, open_dialog dialog) { + this.device = device; + this.dialog = dialog; + t = new Thread(this); + t.start(); + } + } + + class open_dialog + extends AltosUIDialog + implements ActionListener + { + AltosUIFrame owner; + + private JLabel opening_label; + private JButton cancel_button; + + boolean done = false; + + AltosLink link = null; + + open_task open = null; + + public void open_exception(Exception e) { + System.out.printf("open_exception\n"); + setVisible(false); + exception(e); + done = true; + } + + public void open_success(AltosLink link) { + System.out.printf("open_success\n"); + setVisible(false); + this.link = link; + done = true; + } + + public void open_failure() { + System.out.printf("open_failure\n"); + setVisible(false); + done = true; + } + + public void open_cancel() { + System.out.printf("open_cancel\n"); + setVisible(false); + done = true; + } + + public AltosLink do_open(open_task open) throws InterruptedException { + this.open = open; + setVisible(true); + return link; + } + + public void actionPerformed(ActionEvent e) { + String cmd = e.getActionCommand(); + + if (cmd.equals("cancel")) + if (open != null) + open.cancel(); + done = true; + setVisible(false); + } + + public open_dialog(AltosUIFrame in_owner) { + super(in_owner, "Open Flash Target Device", true); + owner = in_owner; + + Container pane = getContentPane(); + GridBagConstraints c = new GridBagConstraints(); + Insets i = new Insets(4,4,4,4); + + + pane.setLayout(new GridBagLayout()); + + opening_label = new JLabel("Opening Device"); + c.fill = GridBagConstraints.HORIZONTAL; + c.anchor = GridBagConstraints.LINE_START; + c.insets = i; + c.weightx = 0; + c.weighty = 0; + + c.gridx = 0; + c.gridy = 0; + + pane.add(opening_label, c); + + cancel_button = new JButton("Cancel"); + cancel_button.addActionListener(this); + cancel_button.setActionCommand("cancel"); + + c.gridy = 1; + pane.add(cancel_button, c); + pack(); + setLocationRelativeTo(owner); + } + } + + private boolean open_device() throws InterruptedException { + + open_dialog dialog = new open_dialog(frame); + + open_task open = new open_task(device, dialog); + + link = dialog.do_open(open); + + return link != null; } /* -- cgit v1.2.3 From c2c7873695ee2dc1b6fd153b67accad9693937aa Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 2 Oct 2018 17:03:28 -0700 Subject: altosui: Fetch RF calibration value for TBT v4.0 units from web We shipped a pile of TBT v4.0 units without programming the RF calibration value into flash. This change checks to see if the target is in the right serial number range and has the default RF calibration value, in which case it fetches the RF calibration value from our web site. Signed-off-by: Keith Packard --- altoslib/AltosLib.java | 3 +++ altoslib/AltosRomconfig.java | 38 +++++++++++++++++++++++++++++++++++++- altoslib/Makefile.am | 4 +++- altosuilib/AltosFlashUI.java | 11 +++++++++++ 4 files changed, 54 insertions(+), 2 deletions(-) (limited to 'altosuilib/AltosFlashUI.java') diff --git a/altoslib/AltosLib.java b/altoslib/AltosLib.java index 254448d0..40d7a27b 100644 --- a/altoslib/AltosLib.java +++ b/altoslib/AltosLib.java @@ -230,6 +230,9 @@ public class AltosLib { public static final String launch_sites_env = "LAUNCH_SITES"; // public static final String launch_sites_url = "file:///home/keithp/misc/text/altusmetrum/AltOS/launch-sites.txt"; + public static final String unit_info_url = "https://altusmetrum.org/cgi-bin/unitinfo.cgi?sn=%d"; + public static final String unit_info_env = "UNIT_INFO"; + public static final int ao_telemetry_standard_len = 32; public static final int ao_telemetry_0_9_len = 95; public static final int ao_telemetry_0_8_len = 94; diff --git a/altoslib/AltosRomconfig.java b/altoslib/AltosRomconfig.java index ccd01274..ebeb76f3 100644 --- a/altoslib/AltosRomconfig.java +++ b/altoslib/AltosRomconfig.java @@ -19,9 +19,11 @@ 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; @@ -117,6 +119,29 @@ public class AltosRomconfig { 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); @@ -131,7 +156,18 @@ public class AltosRomconfig { } 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; } } diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 7c5d767d..92976332 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -183,7 +183,9 @@ altoslib_JAVA = \ AltosMapLoader.java \ AltosMapTypeListener.java \ AltosJson.java \ - AltosVersion.java + AltosVersion.java \ + AltosUnitInfo.java \ + AltosUnitInfoListener.java JAR=altoslib_$(ALTOSLIB_VERSION).jar diff --git a/altosuilib/AltosFlashUI.java b/altosuilib/AltosFlashUI.java index 6c9cae52..b91776aa 100644 --- a/altosuilib/AltosFlashUI.java +++ b/altosuilib/AltosFlashUI.java @@ -325,6 +325,17 @@ public class AltosFlashUI return false; } + if (existing_config.radio_calibration_broken) { + int ret = JOptionPane.showConfirmDialog(this, + String.format("Radio calibration value %d may be incorrect\nFlash anyways?", + existing_config.radio_calibration), + "Radio Calibration Invalid", + JOptionPane.YES_NO_OPTION); + if (ret != JOptionPane.YES_OPTION) + return false; + } + + new_config = AltosRomconfigUI.show(frame, existing_config); if (new_config == null) return false; -- cgit v1.2.3