checkpoint
[slipway.git] / src / edu / berkeley / obits / device / atmel / AvrDrone.java
1 package edu.berkeley.obits.device.atmel;
2
3 import edu.berkeley.slipway.*;
4 import edu.berkeley.obits.*;
5 import org.ibex.util.Log;
6 import java.io.*;
7 import java.util.*;
8 import gnu.io.*;
9
10 /** the "host" side of the AVR Drone; see AvrDrone.c for the other side */
11 public class AvrDrone extends AtmelDevice {
12
13     private final DataInputStream in;
14     private final DataOutputStream out;
15     private final Board board;
16
17     public AvrDrone(Board b) throws IOException {
18         this.board = b;
19         this.out = new DataOutputStream(b.getOutputStream());
20         this.in = new DataInputStream(b.getInputStream());
21         init();
22     } 
23
24     public void reset() throws DeviceException {
25         try {
26             board.reset();
27         } catch (IOException e) {
28             throw new DeviceException(e);
29         }
30     }
31
32     private void init() throws IOException {
33         byte[] bytes = new byte[6];
34         int i=0;
35
36         out.write(0);
37         out.flush();
38
39         // read any crap that might be left in the buffer
40         while(true) {
41             System.arraycopy(bytes, 1, bytes, 0, 5);
42             bytes[5] = in.readByte();
43             i++;
44             System.out.print("\rsignature: read \"" + new String(bytes) + "\"                   ");
45             if (bytes[0] == (byte)'O' &&
46                 bytes[1] == (byte)'B' &&
47                 bytes[2] == (byte)'I' &&
48                 bytes[3] == (byte)'T' &&
49                 bytes[4] == (byte)'S') {
50                 System.out.println("\rsignature: got proper signature                  ");
51                 break;
52             }
53         }
54
55     }
56
57     public synchronized void scanFPGA(boolean on) throws DeviceException {
58         try {
59             if (on) {
60                 out.writeByte(3);
61                 out.flush();
62             } else {
63                 // FIXME
64             }
65         } catch (IOException e) { throw new DeviceException(e); }
66     }
67     // fixme!
68     public static int retval = 0;
69     public synchronized int readCount() throws DeviceException {
70         try {
71             if (reader != null) {
72                 reader.start();
73                 reader = null;
74             }
75             ByteCallback bc = new ByteCallback() {
76                     public synchronized void call(byte b) throws Exception {
77                         retval =
78                             ((b & 0xff) << 24) |
79                             ((in.read() & 0xff) << 16) |
80                             ((in.read() & 0xff) << 8) |
81                             ((in.read() & 0xff) << 0);
82                         this.notify();
83                     }
84                 };
85             synchronized(bc) {
86                 callbacks.add(bc);
87                 out.writeByte(6);
88                 out.flush();
89                 bc.wait();
90             }
91             return retval;
92         } catch (Exception e) { throw new DeviceException(e); }
93     }
94
95     public static interface ByteCallback {
96         public void call(byte b) throws Exception;
97     }
98
99     private Vector callbacks = new Vector();
100
101     private Thread reader = new Thread() {
102             public void run() {
103                 System.out.println("*** reader thread begun");
104                 while(true) {
105                     try {
106                         byte b = in.readByte();
107                         ByteCallback bc = (ByteCallback)callbacks.remove(0);
108                         bc.call(b);
109                     } catch (Exception e) {
110                         e.printStackTrace();
111                     }
112                 }
113             }
114         };
115
116     public synchronized void readBus(ByteCallback bc) throws DeviceException {
117         try {
118             callbacks.add(bc);
119             out.writeByte(2);
120             out.flush();
121             if (reader != null) {
122                 reader.start();
123                 reader = null;
124             }
125         } catch (IOException e) { throw new DeviceException(e); }
126     }
127
128     public synchronized void readInterrupts(ByteCallback bc) throws DeviceException {
129         try {
130             callbacks.add(bc);
131             out.writeByte(6);
132             out.flush();
133             if (reader != null) {
134                 reader.start();
135                 reader = null;
136             }
137         } catch (IOException e) { throw new DeviceException(e); }
138     }
139
140     private byte[][][] cache = new byte[24][][];
141     public /*synchronized*/ byte mode4(int z, int y, int x) throws DeviceException {
142         if (cache[x]==null) return 0;
143         if (cache[x][y]==null) return 0;
144         return cache[x][y][z];
145     }
146
147     int lastz = 0;
148     int lastx = 0;
149     int lasty = 0;
150     public static int save = 0;
151     public static int saveof = 0;
152     public /*synchronized*/ void mode4(int z, int y, int x, int d) throws DeviceException {
153         try {
154             /*
155             Log.info(this, "writing configuration frame [zyxd]: " +
156                       pad(1, Integer.toString(z&0xff, 16)) + " " +
157                       pad(1, Integer.toString(y&0xff, 16)) + " " +
158                       pad(1, Integer.toString(x&0xff, 16)) + " " +
159                       pad(1, Integer.toString(d&0xff, 16))
160                       );
161             */
162             boolean zchange = z!=lastz;
163             boolean ychange = y!=lasty;
164             boolean xchange = x!=lastx;
165             boolean zinc    = z==lastz+1;
166             boolean yinc    = y==lasty+1;
167             boolean xinc    = x==lastx+1;
168             boolean zdec    = z==lastz-1;
169             boolean ydec    = y==lasty-1;
170             boolean xdec    = x==lastx-1;
171             
172             out.writeByte(1);
173             out.writeByte(z);
174             out.writeByte(y);
175             out.writeByte(x);
176             saveof++;
177             lastz = z;
178             lastx = x;
179             lasty = y;
180             out.writeByte(d);
181
182             if (cache[x & 0xff]==null) cache[x & 0xff] = new byte[24][];
183             if (cache[x & 0xff][y & 0xff]==null) cache[x & 0xff][y & 0xff] = new byte[256];
184             cache[x & 0xff][y & 0xff][z & 0xff] = (byte)(d & 0xff);
185         } catch (IOException e) { throw new DeviceException(e); }
186     }
187
188     public /*synchronized*/ void flush() throws DeviceException {
189         try {
190             out.flush();
191         } catch (IOException e) { throw new DeviceException(e); }
192     }
193
194     private String pad(int i, String s) { if (s.length()>i) return s; return "0"+pad((i-1),s); }
195
196 }