it works
[slipway.git] / src / edu / berkeley / obits / device / atmel / ChipImpl.java
1 package edu.berkeley.obits.device.atmel;
2 import com.ftdi.usb.*;
3 import java.io.*;
4
5 public class ChipImpl extends Chip {
6
7     public void doReset() {
8         dbangmode();
9         clk(false);
10         data(false);
11         con(false);
12         super.doReset();
13         dmask &= ~(1<<7);
14         dbangmode();
15     }
16     public void int3(boolean on) { throw new RuntimeException("not connected"); }
17     public boolean porte(int pin) { throw new RuntimeException("not connected"); }
18
19     int porte = 0;
20     public void porte(int pin, boolean b) {
21         porte = (~(1<<pin)) | (b ? (1<<pin) : 0);
22         if (pin==4) {
23             dbang(2, b);
24             flush();
25         }
26     }
27
28     public void config(boolean bit) { config(bit?1:0, 1); }
29
30     private SWIGTYPE_p_ftdi_context context;
31     private int bits = 0;
32
33     public ChipImpl() {
34         context = example.new_ftdi_context();
35
36         int result = example.ftdi_init(context);
37         if (result != 0)
38             throw new RuntimeException("ftdi_initErr() returned " + result);
39
40         result = example.ftdi_usb_open(context, 0x6666, 0x3133);
41         if (result != 0)
42             throw new RuntimeException("ftdi_usb_open() returned " + result);
43
44         //result = example.ftdi_set_baudrate(context, 750 * 1000);
45         result = example.ftdi_set_baudrate(context, 750 * 1000);
46         if (result != 0)
47             throw new RuntimeException("ftdi_set_baudrate() returned " + result);
48         result = example.ftdi_set_line_property(context, 8, 0, 0);
49         if (result != 0)
50             throw new RuntimeException("ftdi_set_baudrate() returned " + result);
51
52         doReset();
53     }
54
55     public int readPins() {
56         byte[] b = new byte[1];
57         int result = example.ftdi_read_pins(context, b);
58         if (result != 0)
59             throw new RuntimeException("ftdi_read_pins() returned " + result);
60         return b[0];
61     }
62
63     public void write(int out) {
64         byte[] b = new byte[1];
65         int result = 0;
66         b[0] = (byte)out;
67         while(result==0)
68             result = example.ftdi_write_data(context, b, 1);
69     }
70
71     private OutputStream os = new ChipOutputStream();
72     private InputStream  is = new ChipInputStream();
73
74     public OutputStream getOutputStream() {
75         //example.ftdi_write_data_set_chunksize(context, 32);
76         return os;
77     }
78     public InputStream  getInputStream() { return is; }
79
80     public class ChipInputStream extends InputStream {
81         public int available() throws IOException {
82             // FIXME
83             return 1;
84         }
85         public long skip(long l) throws IOException {
86             throw new RuntimeException("not supported");
87         }
88         public int read() throws IOException {
89             System.out.println("read()");
90             byte[] b = new byte[1];
91             int result = 0;
92             while(result==0)
93                 result = read(b, 0, 1);
94             if (result==-1)
95                 throw new IOException("ftdi_read_pins() returned " + result);
96             return b[0] & 0xff;
97         }
98         public int read(byte[] b, int off, int len) throws IOException {
99             System.out.println("read("+off+","+len+")");
100             // FIXME: blocking reads?
101             int result = 0;
102             while(true) {
103                 if (len==0) return 0;
104                 synchronized(ChipImpl.this) {
105                     byte[] b0 = new byte[len];
106                     result = example.ftdi_read_data(context, b0, len);
107                     if (result == -1)
108                         throw new IOException("ftdi_read_pins() returned " + result);
109                     if (result>0) {
110                         System.arraycopy(b0, 0, b, off, result);
111                         System.out.println("  return " + result);
112                         return result;
113                     }
114                 }
115                 Thread.yield();
116             }
117         }
118     }
119
120     public class ChipOutputStream extends OutputStream {
121         public void write(int b) throws IOException {
122             byte[] d = new byte[1];
123             d[0] = (byte)b;
124             write(d, 0, 1);
125         }
126         public void write(byte[] b, int off, int len) throws IOException {
127             byte[] b2 = new byte[64];
128             while(len > 0) {
129                 System.arraycopy(b, off, b2, 0, Math.min(b2.length, len));
130                 synchronized(ChipImpl.this) {
131                     int result = example.ftdi_write_data(context, b2, Math.min(b2.length, len));
132                     if (result < 0)
133                         throw new IOException("ftdi_write_data() returned " + result);
134                     off += result;
135                     len -= result;
136                 }
137             }
138         }
139     }
140
141     public int read() {
142         byte[] b = new byte[1];
143         int result = 0;
144         while(result==0)
145             result = example.ftdi_read_data(context, b, 1);
146         if (result != 1)
147             throw new RuntimeException("ftdi_read_pins() returned " + result);
148         return (b[0] & 0xff);
149     }
150
151     ByteArrayOutputStream baos = new ByteArrayOutputStream();
152     public void flush() {
153         byte[] bytes = baos.toByteArray();
154         baos = new ByteArrayOutputStream();
155         dbang(bytes, bytes.length);
156     }
157     public boolean buffered = false;
158     public void buffered() { buffered = true; }
159     public void buffered(boolean buf) { buffered = buf; }
160     public void config(int dat) { config(dat, 8); }
161     public void config(int dat, int numbits) {
162         for(int i=(numbits-1); i>=0; i--) {
163             boolean bit = (dat & (1<<i)) != 0;
164             data(bit);
165             clk(true);
166             clk(false);
167         }
168     }
169
170     public void reset(boolean on) {
171         bits = on ? (1<<1) : 0;
172         cbangmode();
173         //dbang(0, on);
174     }
175     public void avrrst(boolean on) {
176         dbang(7, on);
177     }
178     public boolean initErr() { return (readPins() & (1<<4))!=0; }
179     public void clk(boolean on) { dbang(6, on); }
180     public void data(boolean on) { dbang(5, on); }
181
182     public boolean con() {
183
184         /*
185         mask &= ~(1<<0);
186         cbangmode();
187         boolean ret = (readPins() & (1<<0)) != 0;
188         dbangmode();
189         return ret;
190         */
191
192
193
194         dmask &= ~(1<<0);
195         dbangmode();
196         return (readPins() & (1<<0)) != 0;
197
198     }
199     public void con(boolean on) {
200
201         /*
202         mask |= (1<<0);
203         bits = on ? (1<<0) : 0;
204         cbangmode();
205         */
206
207
208         dmask |= (1<<0);
209         dbangmode();
210         dbang(0, on);
211
212     }
213
214     private static int mask =
215         (1<<0) |
216         (1<<1)// |
217         //(1<<2) |
218         //(1<<3)
219         ;
220
221     private static int dmask =
222         //(1<<0) |
223
224         (1<<1) |
225         (1<<2) |
226
227         //(1<<3) |
228         //(1<<4) |
229         (1<<5) |
230         (1<<6) |
231         (1<<7);
232
233     public void purge() {
234         example.ftdi_usb_purge_buffers(context);
235     }
236     public void uart() {
237         int result = example.ftdi_set_bitmode(context, (short)0, (short)0x00);
238         if (result != 0)
239             throw new RuntimeException("ftdi_set_bitmode() returned " + result);
240
241         result = example.ftdi_setflowctrl(context, 1 << 8);
242         if (result != 0)
243             throw new RuntimeException("ftdi_setflowcontrol() returned " +
244                                        result);
245
246     }
247     public void dbangmode() {
248         int result = example.ftdi_set_bitmode(context, (short)dmask, (short)0x01);
249         if (result != 0)
250             throw new RuntimeException("ftdi_set_bitmode() returned " + result);
251     }
252
253     private void cbangmode() {
254         int result = example.ftdi_set_bitmode(context, (short)((mask << 4) | bits), (short)0x20);
255         if (result != 0)
256             throw new RuntimeException("ftdi_set_bitmode() returned " + result);
257     }
258
259     private int dbits = 0;
260     private void dbang(int bit, boolean val) {
261         dbits = val ? (dbits | (1 << bit)) : (dbits & (~(1 << bit)));
262         if (buffered) {
263             baos.write((byte)dbits);
264         } else {
265             dbang((byte)dbits);
266         }
267     }
268     int write = 0;
269     private void dbang(byte by) {
270         byte[] b = new byte[1];
271         b[0] = by;
272         int result = example.ftdi_write_data(context, b, 1);
273         if (result != 1)
274             throw new RuntimeException("ftdi_write_data() returned " + result);
275     }
276     int queued = 0;
277     private void dbang(byte[] b, int len) {
278         example.ftdi_write_data(context, b, len);
279     }
280 }