checkpoint
[slipway.git] / src / edu / berkeley / slipway / FtdiBoard.java
1 package edu.berkeley.slipway;
2
3 import com.ftdi.usb.*;
4 import com.atmel.fpslic.*;
5 import edu.berkeley.obits.*;
6 import org.ibex.util.*;
7 import java.io.*;
8 import java.util.*;
9 import gnu.io.*;
10
11 public class FtdiBoard extends Fpslic implements Board {
12
13     static {
14         System.load(new File("build/"+System.mapLibraryName("FtdiUartNative")).getAbsolutePath());
15     }
16
17     private final FpslicBoot chip;
18     private final DataInputStream in;
19     private final DataOutputStream out;
20
21     public InputStream getInputStream() { return in; }
22     public OutputStream getOutputStream() { return out; }
23
24     public FtdiBoard() throws Exception {
25         chip = new FpslicBoot(new FpslicBootPinsUsb(new FtdiUart(0x6666, 0x3133, 1500 * 1000)));
26         String bstFile = this.getClass().getName();
27         bstFile = bstFile.substring(0, bstFile.lastIndexOf('.'));
28         bstFile = bstFile.replace('.', '/')+"/slipway_drone.bst";
29         boot(new InputStreamReader(this.getClass().getClassLoader().getResourceAsStream(bstFile)));
30         in = new DataInputStream(chip.getInputStream());
31         out = new DataOutputStream(chip.getOutputStream());
32         for(int i=0; i<255; i++) out.write(0);
33         out.flush();
34     }
35
36     public void reset() throws IOException {
37         chip.reset();
38     }
39
40     public void boot(Reader r) throws Exception {
41
42         chip.selfTest();
43
44         int total = 75090/9;
45         OutputStream os = new ProgressOutputStream("bootstrap bitstream:", chip.getConfigStream(), total);
46         BufferedReader br = new BufferedReader(r);
47
48         int bytes = 0;
49         while(true) {
50             String s = br.readLine();
51             if (s==null) break;
52             bytes++;
53             os.write((byte)Integer.parseInt(s, 2));
54             if ((bytes % 1000)==0) os.flush();
55         }
56         os.close();
57     }
58
59     public static String pad(String s, int i) {
60         if (s.length() >= i) return s;
61         return "0"+pad(s, i-1);
62     }
63
64
65     // AvrDrone leftovers //////////////////////////////////////////////////////////////////////////////
66
67     private void init() throws IOException {
68         byte[] bytes = new byte[6];
69         int i=0;
70
71         out.write(0);
72         out.flush();
73
74         // read any crap that might be left in the buffer
75         while(true) {
76             System.arraycopy(bytes, 1, bytes, 0, 5);
77             bytes[5] = in.readByte();
78             i++;
79             System.out.print("\rsignature: read \"" + new String(bytes) + "\"                   ");
80             if (bytes[0] == (byte)'O' &&
81                 bytes[1] == (byte)'B' &&
82                 bytes[2] == (byte)'I' &&
83                 bytes[3] == (byte)'T' &&
84                 bytes[4] == (byte)'S') {
85                 System.out.println("\rsignature: got proper signature                  ");
86                 break;
87             }
88         }
89
90     }
91
92     public synchronized void scanFPGA(boolean on) throws IOException {
93         if (on) {
94             out.writeByte(3);
95             out.flush();
96         } else {
97             // FIXME
98         }
99     }
100     // fixme!
101     public static int retval = 0;
102     public synchronized int readCount() {
103         try {
104             if (reader != null) {
105                 reader.start();
106                 reader = null;
107             }
108             ByteCallback bc = new ByteCallback() {
109                     public synchronized void call(byte b) throws Exception {
110                         retval =
111                             ((b & 0xff) << 24) |
112                             ((in.read() & 0xff) << 16) |
113                             ((in.read() & 0xff) << 8) |
114                             ((in.read() & 0xff) << 0);
115                         this.notify();
116                     }
117                 };
118             synchronized(bc) {
119                 callbacks.add(bc);
120                 out.writeByte(6);
121                 out.flush();
122                 bc.wait();
123             }
124             return retval;
125         } catch (Exception e) { throw new RuntimeException(e); }
126     }
127
128     public static interface ByteCallback {
129         public void call(byte b) throws Exception;
130     }
131
132     private Vector callbacks = new Vector();
133
134     private Thread reader = new Thread() {
135             public void run() {
136                 System.out.println("*** reader thread begun");
137                 while(true) {
138                     try {
139                         byte b = in.readByte();
140                         ByteCallback bc = (ByteCallback)callbacks.remove(0);
141                         bc.call(b);
142                     } catch (Exception e) {
143                         e.printStackTrace();
144                     }
145                 }
146             }
147         };
148
149     public synchronized void readBus(ByteCallback bc) throws IOException {
150         callbacks.add(bc);
151         out.writeByte(2);
152         out.flush();
153         if (reader != null) {
154             reader.start();
155             reader = null;
156         }
157     }
158
159     public synchronized void readInterrupts(ByteCallback bc) throws IOException {
160         callbacks.add(bc);
161         out.writeByte(6);
162         out.flush();
163         if (reader != null) {
164             reader.start();
165             reader = null;
166         }
167     }
168
169     private byte[][][] cache = new byte[24][][];
170     public /*synchronized*/ byte mode4(int z, int y, int x) {
171         if (cache[x]==null) return 0;
172         if (cache[x][y]==null) return 0;
173         return cache[x][y][z];
174     }
175
176     int lastz = 0;
177     int lastx = 0;
178     int lasty = 0;
179     public static int save = 0;
180     public static int saveof = 0;
181     public /*synchronized*/ void mode4(int z, int y, int x, int d) {
182         try {
183             out.writeByte(1);
184             out.writeByte(z);
185             out.writeByte(y);
186             out.writeByte(x);
187             saveof++;
188             lastz = z;
189             lastx = x;
190             lasty = y;
191             out.writeByte(d);
192
193             if (cache[x & 0xff]==null) cache[x & 0xff] = new byte[24][];
194             if (cache[x & 0xff][y & 0xff]==null) cache[x & 0xff][y & 0xff] = new byte[256];
195             cache[x & 0xff][y & 0xff][z & 0xff] = (byte)(d & 0xff);
196         } catch (IOException e) {
197             throw new RuntimeException(e);
198         }
199     }
200
201     public /*synchronized*/ void flush() {
202         try {
203             out.flush();
204         } catch (IOException e) {
205             throw new RuntimeException(e);
206         }
207     }
208
209     private String pad(int i, String s) { if (s.length()>i) return s; return "0"+pad((i-1),s); }
210
211 }