2 * Copyright © 2013 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; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
19 package org.altusmetrum.altoslib_14;
23 public class AltosSelfFlash extends AltosProgrammer {
25 FileInputStream input;
29 AltosFlashListener listener;
30 AltosRomconfig rom_config;
32 void action(String s, int percent) {
33 if (listener != null && !aborted)
34 listener.position(s, percent);
37 void action(int part, int total) {
38 int percent = 100 * part / total;
39 action(String.format("%d/%d (%d%%)",
40 part, total, percent),
44 byte[] read_memory(long addr, int len) throws InterruptedException, IOException {
46 byte[] data = new byte[len];
48 for (int offset = 0; offset < len; offset += 0x100) {
49 link.printf("R %x\n", addr + offset);
50 byte[] reply = link.get_binary_reply(5000, 0x100);
53 throw new IOException("Read device memory timeout");
54 for (b = 0; b < 0x100 && b + offset < len; b++)
55 data[b+offset] = reply[b];
60 AltosHexfile read_hexfile(long addr, int len) throws InterruptedException {
62 byte[] mem = read_memory(addr, len);
64 AltosHexfile hexfile = new AltosHexfile(mem, addr);
67 hexfile.add_symbols(image);
69 } catch (IOException ie) {
74 void write_memory(long addr, byte[] data, int start, int len) {
76 link.printf("W %x\n", addr);
78 for (b = 0; b < len; b++)
79 link.putchar(data[start + b]);
80 for (; b < 0x100; b++)
81 link.putchar((byte) 0xff);
91 if (!check_rom_config())
92 throw new IOException("Invalid rom config settings");
95 * Store desired config values into image
97 rom_config.write(image);
99 int remain = image.data.length;
100 long flash_addr = image.address;
103 action(AltosFlashListener.flash_start, 0);
104 action(0, image.data.length);
105 while (remain > 0 && !aborted) {
106 int this_time = remain;
107 if (this_time > 0x100)
112 write_memory(flash_addr, image.data, image_start, this_time);
114 byte[] check = read_memory(flash_addr, this_time);
115 for (int i = 0; i < this_time; i++)
116 if (check[i] != image.data[image_start + i])
117 throw new IOException(String.format("Flash write failed at 0x%x (%02x != %02x)",
118 image.address + image_start + i,
119 check[i], image.data[image_start + i]));
125 flash_addr += this_time;
126 image_start += this_time;
128 action(image.data.length - remain, image.data.length);
131 action(AltosFlashListener.flash_done, 100);
134 } catch (IOException ie) {
135 action(ie.getMessage(), -1);
137 } catch (InterruptedException ie) {
142 public void close() {
147 } catch (InterruptedException ie) {
153 synchronized public void abort() {
158 private AltosHexfile get_rom() throws InterruptedException {
160 long base = AltosRomconfig.fetch_base(image);
161 long bounds = AltosRomconfig.fetch_bounds(image);
164 System.out.printf("rom base %x bounds %x\n", base, bounds);
165 return read_hexfile(base, (int) (bounds - base));
166 } catch (AltosNoSymbol ns) {
171 public boolean check_rom_config() throws InterruptedException {
175 if (rom_config == null) {
176 AltosHexfile hexfile = get_rom();
178 rom_config = new AltosRomconfig(hexfile);
180 return rom_config != null && rom_config.valid();
183 public void set_romconfig (AltosRomconfig romconfig) {
184 rom_config = romconfig;
187 public AltosRomconfig target_romconfig(AltosUsbId usb_id, String usb_product) throws InterruptedException {
188 if (!check_rom_config())
190 if (rom_config.usb_id == null)
191 rom_config.usb_id = usb_id;
192 if (rom_config.usb_product == null)
193 rom_config.usb_product = usb_product;
197 public AltosRomconfig image_romconfig() {
198 return new AltosRomconfig(image);
201 public AltosSelfFlash(File file, AltosLink link, AltosFlashListener listener)
202 throws IOException, FileNotFoundException, InterruptedException {
205 this.listener = listener;
206 input = new FileInputStream(file);
207 image = new AltosHexfile(input);