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