2 * Copyright © 2010 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
18 package org.altusmetrum.altosuilib_11;
21 import java.awt.event.*;
23 import javax.swing.filechooser.FileNameExtensionFilter;
25 import java.util.concurrent.*;
26 import org.altusmetrum.altoslib_11.*;
28 public class AltosFlashUI
30 implements ActionListener
43 // Hex file with rom image
51 // Desired Rom configuration
52 AltosRomconfig rom_config;
55 AltosProgrammer programmer;
57 private static final String[] pair_programmed_files = {
70 private static final String[] pair_programmed_devices = {
83 private boolean is_pair_programmed() {
86 String name = file.getName();
87 for (int i = 0; i < pair_programmed_files.length; i++) {
88 if (name.startsWith(pair_programmed_files[i]))
93 String name = device.toString();
94 for (int i = 0; i < pair_programmed_devices.length; i++) {
95 if (name.startsWith(pair_programmed_devices[i]))
102 public void actionPerformed(ActionEvent e) {
103 if (e.getSource() == cancel) {
104 if (programmer != null)
109 String cmd = e.getActionCommand();
110 if (e.getID() == -1) {
111 JOptionPane.showMessageDialog(frame,
112 e.getActionCommand(),
114 JOptionPane.ERROR_MESSAGE);
117 } else if (cmd.equals("done")) {
120 } else if (cmd.equals("start")) {
123 pbar.setValue(e.getID());
129 public void build_dialog() {
130 GridBagConstraints c;
131 Insets il = new Insets(4,4,4,4);
132 Insets ir = new Insets(4,4,4,4);
134 pane = getContentPane();
135 pane.setLayout(new GridBagLayout());
137 c = new GridBagConstraints();
138 c.gridx = 0; c.gridy = 0;
139 c.fill = GridBagConstraints.NONE;
140 c.anchor = GridBagConstraints.LINE_START;
142 serial_label = new JLabel("Serial:");
143 pane.add(serial_label, c);
145 c = new GridBagConstraints();
146 c.gridx = 1; c.gridy = 0;
147 c.fill = GridBagConstraints.HORIZONTAL;
149 c.anchor = GridBagConstraints.LINE_START;
151 serial_value = new JLabel("");
152 pane.add(serial_value, c);
154 c = new GridBagConstraints();
155 c.fill = GridBagConstraints.NONE;
156 c.gridx = 0; c.gridy = 1;
157 c.anchor = GridBagConstraints.LINE_START;
159 file_label = new JLabel("File:");
160 pane.add(file_label, c);
162 c = new GridBagConstraints();
163 c.fill = GridBagConstraints.HORIZONTAL;
165 c.gridx = 1; c.gridy = 1;
166 c.anchor = GridBagConstraints.LINE_START;
168 file_value = new JLabel(file.toString());
169 pane.add(file_value, c);
171 pbar = new JProgressBar();
173 pbar.setMaximum(100);
176 pbar.setStringPainted(true);
177 pbar.setPreferredSize(new Dimension(600, 20));
178 c = new GridBagConstraints();
179 c.fill = GridBagConstraints.HORIZONTAL;
180 c.anchor = GridBagConstraints.CENTER;
181 c.gridx = 0; c.gridy = 2;
182 c.gridwidth = GridBagConstraints.REMAINDER;
183 Insets ib = new Insets(4,4,4,4);
187 cancel = new JButton("Cancel");
188 c = new GridBagConstraints();
189 c.fill = GridBagConstraints.NONE;
190 c.anchor = GridBagConstraints.CENTER;
191 c.gridx = 0; c.gridy = 3;
192 c.gridwidth = GridBagConstraints.REMAINDER;
193 Insets ic = new Insets(4,4,4,4);
196 cancel.addActionListener(this);
198 setLocationRelativeTo(frame);
201 void set_serial(int serial_number) {
202 serial_value.setText(String.format("%d", serial_number));
205 static class AltosHexfileFilter extends javax.swing.filechooser.FileFilter {
210 public AltosHexfileFilter(int product, String head, String description) {
211 this.product = product;
213 this.description = description;
216 public boolean accept(File file) {
217 return !file.isFile() || (file.getName().startsWith(head) && file.getName().endsWith(".ihx"));
220 public String getDescription() {
225 static AltosHexfileFilter[] filters = {
226 new AltosHexfileFilter(AltosLib.product_telemetrum, "telemetrum", "TeleMetrum Image"),
227 new AltosHexfileFilter(AltosLib.product_teledongle, "teledongle", "TeleDongle Image"),
228 new AltosHexfileFilter(AltosLib.product_telemega, "telemega", "TeleMega Image"),
229 new AltosHexfileFilter(AltosLib.product_easymini, "easymini", "EasyMini Image"),
230 new AltosHexfileFilter(AltosLib.product_easymega, "easymega", "EasyMega Image"),
233 boolean select_source_file() {
234 JFileChooser hexfile_chooser = new JFileChooser();
236 File firmwaredir = AltosUIPreferences.firmwaredir();
237 if (firmwaredir != null)
238 hexfile_chooser.setCurrentDirectory(firmwaredir);
240 hexfile_chooser.setDialogTitle("Select Flash Image");
242 for (int i = 0; i < filters.length; i++) {
243 hexfile_chooser.addChoosableFileFilter(filters[i]);
245 javax.swing.filechooser.FileFilter ihx_filter = new FileNameExtensionFilter("Flash Image", "ihx");
246 hexfile_chooser.addChoosableFileFilter(ihx_filter);
247 hexfile_chooser.setFileFilter(ihx_filter);
249 if (!is_pair_programmed() && !device.matchProduct(AltosLib.product_altusmetrum)) {
250 for (int i = 0; i < filters.length; i++) {
251 if (device != null && device.matchProduct(filters[i].product))
252 hexfile_chooser.setFileFilter(filters[i]);
256 int returnVal = hexfile_chooser.showOpenDialog(frame);
258 if (returnVal != JFileChooser.APPROVE_OPTION)
260 file = hexfile_chooser.getSelectedFile();
263 AltosUIPreferences.set_firmwaredir(file.getParentFile());
268 boolean select_device() {
269 int product = AltosLib.product_any;
271 device = AltosDeviceUIDialog.show(frame, AltosLib.product_any);
278 boolean update_rom_config_info(AltosRomconfig existing_config) {
279 AltosRomconfig new_config;
280 new_config = AltosRomconfigUI.show(frame, existing_config);
281 if (new_config == null)
283 rom_config = new_config;
284 set_serial(rom_config.serial_number);
289 void exception (Exception e) {
290 if (e instanceof FileNotFoundException) {
291 JOptionPane.showMessageDialog(frame,
292 ((FileNotFoundException) e).getMessage(),
294 JOptionPane.ERROR_MESSAGE);
295 } else if (e instanceof AltosSerialInUseException) {
296 JOptionPane.showMessageDialog(frame,
297 String.format("Device \"%s\" already in use",
298 device.toShortString()),
300 JOptionPane.ERROR_MESSAGE);
301 } else if (e instanceof IOException) {
302 JOptionPane.showMessageDialog(frame,
305 JOptionPane.ERROR_MESSAGE);
309 class flash_task implements Runnable, AltosFlashListener {
312 AltosProgrammer programmer;
314 public void position(String in_s, int in_percent) {
315 final String s = in_s;
316 final int percent = in_percent;
317 Runnable r = new Runnable() {
320 ui.actionPerformed(new ActionEvent(this,
323 } catch (Exception ex) {
327 SwingUtilities.invokeLater(r);
332 if (ui.is_pair_programmed())
333 programmer = new AltosFlash(ui.file, link, this);
335 programmer = new AltosSelfFlash(ui.file, link, this);
337 final AltosRomconfig current_config = programmer.romconfig();
339 final Semaphore await_rom_config = new Semaphore(0);
340 SwingUtilities.invokeLater(new Runnable() {
342 ui.programmer = programmer;
343 ui.update_rom_config_info(current_config);
344 await_rom_config.release();
347 await_rom_config.acquire();
349 if (ui.rom_config != null) {
350 programmer.set_romconfig(ui.rom_config);
353 } catch (InterruptedException ee) {
354 final Exception e = ee;
355 SwingUtilities.invokeLater(new Runnable() {
360 } catch (IOException ee) {
361 final Exception e = ee;
362 SwingUtilities.invokeLater(new Runnable() {
368 if (programmer != null)
373 public flash_task(AltosFlashUI in_ui) {
375 t = new Thread(this);
382 private boolean open_device() throws InterruptedException {
384 link = new AltosSerial(device);
385 if (is_pair_programmed())
389 throw new IOException(String.format("%s: open failed", device.toShortString()));
391 while (!link.is_loader()) {
394 java.util.List<AltosDevice> devices = null;
396 for (int tries = 0; tries < 10; tries++) {
398 devices = AltosUSBDevice.list(AltosLib.product_altusmetrum);
399 if (devices.size() != 0)
403 if (devices.size() == 1)
404 device = devices.get(0);
406 device = AltosDeviceUIDialog.show(frame, AltosLib.product_altusmetrum);
410 link = new AltosSerial(device);
413 } catch (AltosSerialInUseException ee) {
415 } catch (FileNotFoundException fe) {
417 } catch (IOException ie) {
424 * Execute the steps for flashing
425 * a device. Note that this returns immediately;
426 * this dialog is not modal
429 if (!select_device())
431 if (!select_source_file())
436 } catch (InterruptedException ie) {
440 flash_task f = new flash_task(this);
443 public static void show(AltosUIFrame frame) {
444 AltosFlashUI ui = new AltosFlashUI(frame);
448 public AltosFlashUI(AltosUIFrame in_frame) {
449 super(in_frame, "Program Altusmetrum Device", false);