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