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