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.altoslib_10;
22 public class AltosDebug {
24 public static final byte WR_CONFIG = 0x1d;
25 public static final byte RD_CONFIG = 0x24;
26 public static final byte CONFIG_TIMERS_OFF = (1 << 3);
27 public static final byte CONFIG_DMA_PAUSE = (1 << 2);
28 public static final byte CONFIG_TIMER_SUSPEND = (1 << 1);
29 public static final byte SET_FLASH_INFO_PAGE = (1 << 0);
31 public static final byte GET_PC = 0x28;
32 public static final byte READ_STATUS = 0x34;
33 public static final byte STATUS_CHIP_ERASE_DONE = (byte) (1 << 7);
34 public static final byte STATUS_PCON_IDLE = (1 << 6);
35 public static final byte STATUS_CPU_HALTED = (1 << 5);
36 public static final byte STATUS_POWER_MODE_0 = (1 << 4);
37 public static final byte STATUS_HALT_STATUS = (1 << 3);
38 public static final byte STATUS_DEBUG_LOCKED = (1 << 2);
39 public static final byte STATUS_OSCILLATOR_STABLE = (1 << 1);
40 public static final byte STATUS_STACK_OVERFLOW = (1 << 0);
42 public static final byte SET_HW_BRKPNT = 0x3b;
43 public static byte HW_BRKPNT_N(byte n) { return (byte) ((n) << 3); }
44 public static final byte HW_BRKPNT_N_MASK = (0x3 << 3);
45 public static final byte HW_BRKPNT_ENABLE = (1 << 2);
47 public static final byte HALT = 0x44;
48 public static final byte RESUME = 0x4c;
49 public static byte DEBUG_INSTR(byte n) { return (byte) (0x54|(n)); }
50 public static final byte STEP_INSTR = 0x5c;
51 public static byte STEP_REPLACE(byte n) { return (byte) (0x64|(n)); }
52 public static final byte GET_CHIP_ID = 0x68;
55 private AltosLink link;
59 void ensure_debug_mode() throws InterruptedException {
67 void dump_memory(String header, int address, byte[] bytes, int start, int len) {
68 System.out.printf("%s\n", header);
69 for (int j = 0; j < len; j++) {
72 System.out.printf("\n");
73 System.out.printf ("%04x:", address + j);
75 System.out.printf(" %02x", bytes[start + j]);
77 System.out.printf("\n");
83 } catch (InterruptedException ie) {
90 public void write_memory(int address, byte[] bytes, int start, int len) throws InterruptedException {
92 // dump_memory("write_memory", address, bytes, start, len);
93 link.printf("O %x %x\n", len, address);
94 for (int i = 0; i < len; i++)
95 link.printf("%02x", bytes[start + i]);
98 public void write_memory(int address, byte[] bytes) throws InterruptedException {
99 write_memory(address, bytes, 0, bytes.length);
105 public byte[] read_memory(int address, int length)
106 throws IOException, InterruptedException {
107 byte[] data = new byte[length];
111 link.printf("I %x %x\n", length, address);
115 String line = link.get_reply();
117 throw new IOException("No reply");
120 if (!AltosLib.ishex(line) || line.length() % 2 != 0)
121 throw new IOException(
123 ("Invalid reply \"%s\"", line));
124 int this_time = line.length() / 2;
125 for (int j = 0; j < this_time; j++)
126 data[start + j] = (byte) ((AltosLib.fromhex(line.charAt(j*2)) << 4) +
127 AltosLib.fromhex(line.charAt(j*2+1)));
131 // dump_memory("read_memory", address, data, 0, length);
137 * Write raw bytes to the debug link using the 'P' command
139 public void write_bytes(byte[] bytes) throws IOException, InterruptedException {
142 while (i < bytes.length) {
143 int this_time = bytes.length - i;
147 for (int j = 0; j < this_time; j++)
148 link.printf(" %02x", bytes[i+j]);
154 public void write_byte(byte b) throws IOException, InterruptedException {
155 byte[] bytes = { b };
160 * Read raw bytes from the debug link using the 'G' command
162 public byte[] read_bytes(int length)
163 throws IOException, InterruptedException {
167 link.printf("G %x\n", length);
169 byte[] data = new byte[length];
171 String line = link.get_reply();
174 throw new IOException("Timeout in read_bytes");
176 String tokens[] = line.split("\\s+");
177 for (int j = 0; j < tokens.length; j++) {
178 if (!AltosLib.ishex(tokens[j]) ||
179 tokens[j].length() != 2)
180 throw new IOException(
182 ("Invalid read_bytes reply \"%s\"", line));
185 throw new IOException(
187 ("Invalid read_bytes reply \"%s\"", line));
189 data[i + j] = (byte) Integer.parseInt(tokens[j], 16);
190 } catch (NumberFormatException ne) {
191 throw new IOException(
193 ("Invalid read_bytes reply \"%s\"", line));
201 public byte read_byte() throws IOException, InterruptedException {
202 return read_bytes(1)[0];
205 public byte debug_instr(byte[] instruction) throws IOException, InterruptedException {
206 byte[] command = new byte[1 + instruction.length];
207 command[0] = DEBUG_INSTR((byte) instruction.length);
208 for (int i = 0; i < instruction.length; i++)
209 command[i+1] = instruction[i];
210 write_bytes(command);
214 public byte resume() throws IOException, InterruptedException {
219 public int read_uint16() throws IOException, InterruptedException {
220 byte[] d = read_bytes(2);
221 return ((int) (d[0] & 0xff) << 8) | (d[1] & 0xff);
224 public int read_uint8() throws IOException, InterruptedException {
225 byte[] d = read_bytes(1);
226 return (int) (d[0] & 0xff);
229 public int get_chip_id() throws IOException, InterruptedException {
230 write_byte(GET_CHIP_ID);
231 return read_uint16();
234 public int get_pc() throws IOException, InterruptedException {
236 return read_uint16();
239 public byte read_status() throws IOException, InterruptedException {
240 write_byte(READ_STATUS);
244 static final byte LJMP = 0x02;
246 public void set_pc(int pc) throws IOException, InterruptedException {
247 byte high = (byte) (pc >> 8);
248 byte low = (byte) pc;
249 byte[] jump_mem = { LJMP, high, low };
250 debug_instr(jump_mem);
253 public boolean check_connection() throws IOException, InterruptedException {
254 byte reply = read_status();
255 if ((reply & STATUS_CHIP_ERASE_DONE) == 0)
257 if ((reply & STATUS_PCON_IDLE) != 0)
259 if ((reply & STATUS_POWER_MODE_0) == 0)
264 public AltosRomconfig romconfig() throws InterruptedException {
266 byte[] bytes = read_memory(0xa0, 10);
267 AltosHexfile hexfile = new AltosHexfile (bytes, 0xa0);
268 return new AltosRomconfig(hexfile);
269 } catch (IOException ie) {
271 return new AltosRomconfig();
277 public void reset() {
281 public AltosDebug (AltosLink link) {