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