diff options
| -rw-r--r-- | altoslib/AltosSelfFlash.java | 97 | ||||
| -rw-r--r-- | altoslib/Makefile.am | 1 | ||||
| -rw-r--r-- | altosui/AltosFlashUI.java | 152 | 
3 files changed, 200 insertions, 50 deletions
| diff --git a/altoslib/AltosSelfFlash.java b/altoslib/AltosSelfFlash.java index 0ae797a0..07952d7f 100644 --- a/altoslib/AltosSelfFlash.java +++ b/altoslib/AltosSelfFlash.java @@ -19,14 +19,14 @@ package org.altusmetrum.altoslib_2;  import java.io.*; -public class AltosSelfFlash { +public class AltosSelfFlash extends AltosProgrammer {  	File			file;  	FileInputStream		input;  	AltosHexfile		image;  	AltosLink		link;  	boolean			aborted;  	AltosFlashListener	listener; -	byte[]			read_block, write_block; +	AltosRomconfig		rom_config;  	void action(String s, int percent) {  		if (listener != null && !aborted) @@ -40,23 +40,49 @@ public class AltosSelfFlash {  		       percent);  	} -	void read_block(long addr) { -		link.printf("R %x\n", addr); -		 -	} - -	void read_memory(long addr, int len) { +	byte[] read_memory(long addr, int len) throws InterruptedException, IOException { +		int b; +		byte[]	data = new byte[len]; + +		for (int offset = 0; offset < len; offset += 0x100) { +			link.printf("R %x\n", addr + offset); +			byte[]	reply = link.get_binary_reply(5000, 0x100); +			 +			if (reply == null) +				throw new IOException("Read device memory timeout"); +			for (b = 0; b < len; b++) +				data[b+offset] = reply[b]; +		} +		return data;  	}  	void write_memory(long addr, byte[] data, int start, int len) { -		 +		int b; +		System.out.printf ("write_memory %x %d\n", addr, len); +		link.printf("W %x\n", addr); +		link.flush_output(); +		for (b = 0; b < len; b++) +			link.putchar(data[start + b]); +		for (; b < 0x100; b++) +			link.putchar((byte) 0xff);  	}  	void reboot() { +		System.out.printf("reboot\n"); +		link.printf("a\n"); +		link.flush_output();  	}  	public void flash() {  		try { +			if (!check_rom_config()) +				throw new IOException("Invalid rom config settings"); + +			/* +			 * Store desired config values into image +			 */ +			rom_config.write(image); +  			int remain = image.data.length;  			long flash_addr = image.address;  			int image_start = 0; @@ -89,13 +115,10 @@ public class AltosSelfFlash {  				action(image.data.length - remain, image.data.length);  			}  			if (!aborted) { +				System.out.printf ("done\n");  				action("done", 100); -				if (link != null) { -					reboot(); -				}  			} -			if (link != null) -				link.close(); +			close();  		} catch (IOException ie) {  			action(ie.getMessage(), -1);  			abort(); @@ -105,8 +128,11 @@ public class AltosSelfFlash {  	}  	public void close() { -		if (link != null) +		if (link != null) { +			reboot();  			link.close(); +			link = null; +		}  	}  	synchronized public void abort() { @@ -114,11 +140,36 @@ public class AltosSelfFlash {  		close();  	} +	private AltosHexfile get_rom() { +		System.out.printf("get rom\n"); +		try { +			int base = AltosRomconfig.fetch_base(image); +			int bounds = AltosRomconfig.fetch_bounds(image); +			byte[] data = read_memory(base, bounds - base); +			AltosHexfile hexfile = new AltosHexfile(data, base); +			hexfile.add_symbols(image); +			return hexfile; +		} catch (AltosNoSymbol none) { +			System.out.printf("no symbol %s\n", none.getMessage()); +			return null; +		} catch (InterruptedException ie) { +			return null; +		} catch (IOException ie) { +			return null; +		} + +	} +  	public boolean check_rom_config() { -		if (link == null) +		if (link == null) { +			System.out.printf ("no link\n");  			return true; -		if (rom_config == null) -			rom_config = debug.romconfig(); +		} +		if (rom_config == null) { +			AltosHexfile hexfile = get_rom(); +			if (hexfile != null) +				rom_config = new AltosRomconfig(hexfile); +		}  		return rom_config != null && rom_config.valid();  	} @@ -127,23 +178,19 @@ public class AltosSelfFlash {  	}  	public AltosRomconfig romconfig() { +		System.out.printf("fetch romconfig\n");  		if (!check_rom_config())  			return null;  		return rom_config;  	} -	public AltosFlash(File file, AltosLink link, AltosFlashListener listener) +	public AltosSelfFlash(File file, AltosLink link, AltosFlashListener listener)  		throws IOException, FileNotFoundException, InterruptedException {  		this.file = file;  		this.link = link;  		this.listener = listener; -		this.read_block = new byte[256]; -		this.write_block = new byte[256];  		input = new FileInputStream(file);  		image = new AltosHexfile(input); -		if (link != null) { -			debug.close(); -			throw new IOException("Debug port not connected"); -		} +		System.out.printf ("AltosSelfFlash %x\n", image.address);  	}  }
\ No newline at end of file diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index 919d098f..2c26220b 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -76,6 +76,7 @@ altoslib_JAVA = \  	AltosProgrammer.java \  	AltosReplayReader.java \  	AltosRomconfig.java \ +	AltosSelfFlash.java \  	AltosSensorMM.java \  	AltosSensorEMini.java \  	AltosSensorTM.java \ diff --git a/altosui/AltosFlashUI.java b/altosui/AltosFlashUI.java index 6eccface..7e4cddb1 100644 --- a/altosui/AltosFlashUI.java +++ b/altosui/AltosFlashUI.java @@ -45,18 +45,42 @@ public class AltosFlashUI  	File		file;  	// Debug connection -	AltosDevice	debug_dongle; +	AltosDevice	device; + +	AltosLink	link;  	// Desired Rom configuration  	AltosRomconfig	rom_config;  	// Flash controller -	AltosFlash	flash; +	AltosProgrammer	programmer; + +	private static String[] pair_programmed = { +		"teleballoon", +		"telebt", +		"teledongle", +		"telefire", +		"telemetrum-v0", +		"telemetrum-v1", +		"telemini", +		"telenano", +		"teleshield", +		"teleterra" +	}; + +	private boolean is_pair_programmed() { +		String	name = file.getName(); +		for (int i = 0; i < pair_programmed.length; i++) { +			if (name.startsWith(pair_programmed[i])) +				return true; +		} +		return false; +	}  	public void actionPerformed(ActionEvent e) {  		if (e.getSource() == cancel) { -			if (flash != null) -				flash.abort(); +			if (programmer != null) +				programmer.abort();  			setVisible(false);  			dispose();  		} else { @@ -156,6 +180,33 @@ public class AltosFlashUI  		serial_value.setText(String.format("%d", serial_number));  	} +	static class AltosHexfileFilter extends javax.swing.filechooser.FileFilter { +		int product; +		String head; +		String description; + +		public AltosHexfileFilter(int product, String head, String description) { +			this.product = product; +			this.head = head; +			this.description = description; +		} + +		public boolean accept(File file) { +			return file.getName().startsWith(head) && file.getName().endsWith(".ihx"); +		} + +		public String getDescription() { +			return description; +		} +	} + +	static AltosHexfileFilter[] filters = { +		new AltosHexfileFilter(AltosLib.product_telemetrum, "telemetrum", "TeleMetrum Image"), +		new AltosHexfileFilter(AltosLib.product_teledongle, "teledongle", "TeleDongle Image"), +		new AltosHexfileFilter(AltosLib.product_telemega, "telemega", "TeleMega Image"), +		new AltosHexfileFilter(AltosLib.product_easymini, "easymini", "EasyMini Image"), +	}; +  	boolean select_source_file() {  		JFileChooser	hexfile_chooser = new JFileChooser(); @@ -164,7 +215,24 @@ public class AltosFlashUI  			hexfile_chooser.setCurrentDirectory(firmwaredir);  		hexfile_chooser.setDialogTitle("Select Flash Image"); -		hexfile_chooser.setFileFilter(new FileNameExtensionFilter("Flash Image", "ihx")); + +		for (int i = 0; i < filters.length; i++) { +			hexfile_chooser.addChoosableFileFilter(filters[i]); +		} +		javax.swing.filechooser.FileFilter ihx_filter = new FileNameExtensionFilter("Flash Image", "ihx"); +		hexfile_chooser.addChoosableFileFilter(ihx_filter); +		hexfile_chooser.setFileFilter(ihx_filter); +		 +		if (!device.matchProduct(AltosLib.product_altusmetrum)) { +			for (int i = 0; i < filters.length; i++) { +				System.out.printf ("device %s filter %d\n", device, filters[i].product); +				if (device != null && device.matchProduct(filters[i].product)) { +					System.out.printf ("select filter %s\n", filters[i].head); +					hexfile_chooser.setFileFilter(filters[i]); +				} +			} +		} +  		int returnVal = hexfile_chooser.showOpenDialog(frame);  		if (returnVal != JFileChooser.APPROVE_OPTION) @@ -173,13 +241,16 @@ public class AltosFlashUI  		if (file == null)  			return false;  		AltosUIPreferences.set_firmwaredir(file.getParentFile()); +		  		return true;  	} -	boolean select_debug_dongle() { -		debug_dongle = AltosDeviceUIDialog.show(frame, Altos.product_any); +	boolean select_device() { +		int	product = Altos.product_any; -		if (debug_dongle == null) +		device = AltosDeviceUIDialog.show(frame, Altos.product_any); + +		if (device == null)  			return false;  		return true;  	} @@ -204,7 +275,7 @@ public class AltosFlashUI  		} else if (e instanceof AltosSerialInUseException) {  			JOptionPane.showMessageDialog(frame,  						      String.format("Device \"%s\" already in use", -								    debug_dongle.toShortString()), +								    device.toShortString()),  						      "Device in use",  						      JOptionPane.ERROR_MESSAGE);  		} else if (e instanceof IOException) { @@ -218,7 +289,7 @@ public class AltosFlashUI  	class flash_task implements Runnable, AltosFlashListener {  		AltosFlashUI	ui;  		Thread		t; -		AltosFlash	flash; +		AltosProgrammer	programmer;  		public void position(String in_s, int in_percent) {  			final String s = in_s; @@ -238,14 +309,17 @@ public class AltosFlashUI  		public void run () {  			try { -				flash = new AltosFlash(ui.file, new AltosSerial(ui.debug_dongle), this); +				if (ui.is_pair_programmed()) +					programmer = new AltosFlash(ui.file, link, this); +				else +					programmer = new AltosSelfFlash(ui.file, link, this); -				final AltosRomconfig	current_config = flash.romconfig(); +				final AltosRomconfig	current_config = programmer.romconfig();  				final Semaphore await_rom_config = new Semaphore(0);  				SwingUtilities.invokeLater(new Runnable() {  						public void run() { -							ui.flash = flash; +							ui.programmer = programmer;  							ui.update_rom_config_info(current_config);  							await_rom_config.release();  						} @@ -253,8 +327,8 @@ public class AltosFlashUI  				await_rom_config.acquire();  				if (ui.rom_config != null) { -					flash.set_romconfig(ui.rom_config); -					flash.flash(); +					programmer.set_romconfig(ui.rom_config); +					programmer.flash();  				}  			} catch (InterruptedException ee) {  				final Exception	e = ee; @@ -270,16 +344,9 @@ public class AltosFlashUI  							ui.exception(e);  						}  					}); -			} catch (AltosSerialInUseException ee) { -				final Exception	e = ee; -				SwingUtilities.invokeLater(new Runnable() { -						public void run() { -							ui.exception(e); -						} -					});  			} finally { -				if (flash != null) -					flash.close(); +				if (programmer != null) +					programmer.close();  			}  		} @@ -292,16 +359,51 @@ public class AltosFlashUI  	flash_task	flasher; +	private boolean open_device() { +		try { +			link = new AltosSerial(device); +			if (is_pair_programmed()) +				return true; + +			if (link == null) +				throw new IOException(String.format("%s: open failed", device.toShortString())); + +			while (!link.is_loader()) { +				link.to_loader(); + +				java.util.List<AltosDevice> devices = AltosUSBDevice.list(AltosLib.product_altusmetrum); +				if (devices.size() == 1) +					device = devices.get(0); +				else { +					device = AltosDeviceUIDialog.show(frame, AltosLib.product_altusmetrum); +					if (device == null) +						return false; +				} +				link = new AltosSerial(device); +			} +			return true; +		} catch (AltosSerialInUseException ee) { +			exception(ee); +		} catch (FileNotFoundException fe) { +			exception(fe); +		} catch (IOException ie) { +			exception (ie); +		} +		return false; +	} +  	/*  	 * Execute the steps for flashing  	 * a device. Note that this returns immediately;  	 * this dialog is not modal  	 */  	void showDialog() { -		if (!select_debug_dongle()) +		if (!select_device())  			return;  		if (!select_source_file())  			return; +		if (!open_device()) +			return;  		build_dialog();  		flash_task	f = new flash_task(this);  	} | 
