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.
22 import java.util.concurrent.LinkedBlockingQueue;
23 import java.util.LinkedList;
24 import java.util.Iterator;
25 import altosui.AltosSerial;
26 import altosui.AltosRomconfig;
28 public class AltosDebug extends AltosSerial {
30 static final byte WR_CONFIG = 0x1d;
31 static final byte RD_CONFIG = 0x24;
32 static final byte CONFIG_TIMERS_OFF = (1 << 3);
33 static final byte CONFIG_DMA_PAUSE = (1 << 2);
34 static final byte CONFIG_TIMER_SUSPEND = (1 << 1);
35 static final byte SET_FLASH_INFO_PAGE = (1 << 0);
37 static final byte GET_PC = 0x28;
38 static final byte READ_STATUS = 0x34;
39 static final byte STATUS_CHIP_ERASE_DONE = (byte) (1 << 7);
40 static final byte STATUS_PCON_IDLE = (1 << 6);
41 static final byte STATUS_CPU_HALTED = (1 << 5);
42 static final byte STATUS_POWER_MODE_0 = (1 << 4);
43 static final byte STATUS_HALT_STATUS = (1 << 3);
44 static final byte STATUS_DEBUG_LOCKED = (1 << 2);
45 static final byte STATUS_OSCILLATOR_STABLE = (1 << 1);
46 static final byte STATUS_STACK_OVERFLOW = (1 << 0);
48 static final byte SET_HW_BRKPNT = 0x3b;
49 static byte HW_BRKPNT_N(byte n) { return (byte) ((n) << 3); }
50 static final byte HW_BRKPNT_N_MASK = (0x3 << 3);
51 static final byte HW_BRKPNT_ENABLE = (1 << 2);
53 static final byte HALT = 0x44;
54 static final byte RESUME = 0x4c;
55 static byte DEBUG_INSTR(byte n) { return (byte) (0x54|(n)); }
56 static final byte STEP_INSTR = 0x5c;
57 static byte STEP_REPLACE(byte n) { return (byte) (0x64|(n)); }
58 static final byte GET_CHIP_ID = 0x68;
61 static boolean ishex(int c) {
62 if ('0' <= c && c <= '9')
64 if ('a' <= c && c <= 'f')
66 if ('A' <= c && c <= 'F')
71 static boolean ishex(String s) {
72 for (int i = 0; i < s.length(); i++)
73 if (!ishex(s.charAt(i)))
77 static boolean isspace(int c) {
86 static int fromhex(int c) {
87 if ('0' <= c && c <= '9')
89 if ('a' <= c && c <= 'f')
91 if ('A' <= c && c <= 'F')
98 void ensure_debug_mode() {
106 * Write target memory
108 public void write_memory(int address, byte[] bytes) {
110 printf("O %x %x\n", bytes.length, address);
111 for (int i = 0; i < bytes.length; i++)
112 printf("%02x", bytes[i]);
118 public byte[] read_memory(int address, int length)
119 throws IOException, InterruptedException {
120 byte[] data = new byte[length];
124 printf("I %x %x\n", length, address);
127 String line = get_reply().trim();
128 if (!ishex(line) || line.length() % 2 != 0)
129 throw new IOException(
131 ("Invalid reply \"%s\"", line));
132 int this_time = line.length() / 2;
133 for (int j = 0; j < this_time; j++)
134 data[j] = (byte) ((fromhex(line.charAt(j*2)) << 4) +
135 fromhex(line.charAt(j*2+1)));
143 * Write raw bytes to the debug link using the 'P' command
145 public void write_bytes(byte[] bytes) throws IOException {
148 while (i < bytes.length) {
149 int this_time = bytes.length - i;
153 for (int j = 0; j < this_time; j++)
154 printf(" %02x", bytes[i+j]);
160 public void write_byte(byte b) throws IOException {
161 byte[] bytes = { b };
166 * Read raw bytes from the debug link using the 'G' command
168 public byte[] read_bytes(int length)
169 throws IOException, InterruptedException {
173 printf("G %x\n", length);
175 byte[] data = new byte[length];
177 String line = get_reply().trim();
178 String tokens[] = line.split("\\s+");
179 for (int j = 0; j < tokens.length; j++) {
180 if (!ishex(tokens[j]) ||
181 tokens[j].length() != 2)
182 throw new IOException(
184 ("Invalid read_bytes reply \"%s\"", line));
186 data[i + j] = (byte) Integer.parseInt(tokens[j], 16);
187 } catch (NumberFormatException ne) {
188 throw new IOException(
190 ("Invalid read_bytes reply \"%s\"", line));
198 public byte read_status() throws IOException, InterruptedException {
199 write_byte(READ_STATUS);
200 return read_bytes(2)[0];
203 public boolean check_connection() throws IOException, InterruptedException {
204 byte reply = read_status();
205 System.out.printf("status %x\n", reply);
206 if ((reply & STATUS_CHIP_ERASE_DONE) == 0)
208 if ((reply & STATUS_PCON_IDLE) != 0)
210 if ((reply & STATUS_POWER_MODE_0) == 0)
215 public AltosRomconfig romconfig() {
217 byte[] bytes = read_memory(0xa0, 10);
218 return new AltosRomconfig(bytes, 0);
219 } catch (IOException ie) {
220 } catch (InterruptedException ie) {
222 return new AltosRomconfig();
228 public void reset() {