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