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