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