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; 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.altoslib_5;
22 public class AltosSelfFlash extends AltosProgrammer {
24 FileInputStream input;
28 AltosFlashListener listener;
29 AltosRomconfig rom_config;
31 void action(String s, int percent) {
32 if (listener != null && !aborted)
33 listener.position(s, percent);
36 void action(int part, int total) {
37 int percent = 100 * part / total;
38 action(String.format("%d/%d (%d%%)",
39 part, total, percent),
43 byte[] read_memory(long addr, int len) throws InterruptedException, IOException {
45 byte[] data = new byte[len];
47 for (int offset = 0; offset < len; offset += 0x100) {
48 link.printf("R %x\n", addr + offset);
49 byte[] reply = link.get_binary_reply(5000, 0x100);
52 throw new IOException("Read device memory timeout");
53 for (b = 0; b < len; b++)
54 data[b+offset] = reply[b];
59 void write_memory(long addr, byte[] data, int start, int len) {
61 link.printf("W %x\n", addr);
63 for (b = 0; b < len; b++)
64 link.putchar(data[start + b]);
65 for (; b < 0x100; b++)
66 link.putchar((byte) 0xff);
76 if (!check_rom_config())
77 throw new IOException("Invalid rom config settings");
80 * Store desired config values into image
82 rom_config.write(image);
84 int remain = image.data.length;
85 long flash_addr = image.address;
89 action(0, image.data.length);
90 while (remain > 0 && !aborted) {
91 int this_time = remain;
92 if (this_time > 0x100)
97 write_memory(flash_addr, image.data, image_start, this_time);
99 byte[] check = read_memory(flash_addr, this_time);
100 for (int i = 0; i < this_time; i++)
101 if (check[i] != image.data[image_start + i])
102 throw new IOException(String.format("Flash write failed at 0x%x (%02x != %02x)",
103 image.address + image_start + i,
104 check[i], image.data[image_start + i]));
110 flash_addr += this_time;
111 image_start += this_time;
113 action(image.data.length - remain, image.data.length);
119 } catch (IOException ie) {
120 action(ie.getMessage(), -1);
122 } catch (InterruptedException ie) {
127 public void close() {
132 } catch (InterruptedException ie) {
138 synchronized public void abort() {
143 private AltosHexfile get_rom() throws InterruptedException {
145 int base = AltosRomconfig.fetch_base(image);
146 int bounds = AltosRomconfig.fetch_bounds(image);
147 byte[] data = read_memory(base, bounds - base);
148 AltosHexfile hexfile = new AltosHexfile(data, base);
149 hexfile.add_symbols(image);
151 } catch (AltosNoSymbol none) {
153 } catch (IOException ie) {
159 public boolean check_rom_config() throws InterruptedException {
163 if (rom_config == null) {
164 AltosHexfile hexfile = get_rom();
166 rom_config = new AltosRomconfig(hexfile);
168 return rom_config != null && rom_config.valid();
171 public void set_romconfig (AltosRomconfig romconfig) {
172 rom_config = romconfig;
175 public AltosRomconfig romconfig() throws InterruptedException {
176 if (!check_rom_config())
181 public AltosSelfFlash(File file, AltosLink link, AltosFlashListener listener)
182 throws IOException, FileNotFoundException, InterruptedException {
185 this.listener = listener;
186 input = new FileInputStream(file);
187 image = new AltosHexfile(input);