checkpoint
[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, 1000 * 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 synchronized 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     private OutputStream os = new ChipOutputStream();
64     private InputStream  is = new ChipInputStream();
65
66     public OutputStream getOutputStream() {
67         return os;
68     }
69     public InputStream  getInputStream() {
70         //example.ftdi_read_data_set_chunksize(context, 32);
71         return is;
72     }
73
74     public class ChipInputStream extends InputStream {
75         public int available() throws IOException {
76             // FIXME
77             return 0;
78         }
79         public long skip(long l) throws IOException {
80             throw new RuntimeException("not supported");
81         }
82         public int read() throws IOException {
83             System.out.println("read()");
84             byte[] b = new byte[1];
85             int result = 0;
86             while(result==0)
87                 result = read(b, 0, 1);
88             if (result==-1)
89                 throw new IOException("ftdi_read_pins() returned " + result);
90             return b[0] & 0xff;
91         }
92         public int read(byte[] b, int off, int len) throws IOException {
93             // FIXME: blocking reads?
94             int result = 0;
95             while(true) {
96                 if (len==0) return 0;
97                     byte[] b0 = new byte[len];
98                     synchronized(ChipImpl.this) {
99                         result = example.ftdi_read_data(context, b0, len);
100                     }
101                     if (result == -1)
102                         throw new IOException("ftdi_read_pins() returned " + result);
103                     if (result>0) {
104                         System.arraycopy(b0, 0, b, off, result);
105                         return result;
106                     }
107                 try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); } 
108             }
109         }
110     }
111
112     public class ChipOutputStream extends OutputStream {
113         public void write(int b) throws IOException {
114             byte[] d = new byte[1];
115             d[0] = (byte)b;
116             write(d, 0, 1);
117         }
118         public void write(byte[] b, int off, int len) throws IOException {
119             byte[] b2 = new byte[64];
120             while(len > 0) {
121                 System.arraycopy(b, off, b2, 0, Math.min(b2.length, len));
122                 synchronized(ChipImpl.this) {
123                     int result = example.ftdi_write_data(context, b2, Math.min(b2.length, len));
124                     if (result < 0)
125                         throw new IOException("ftdi_write_data() returned " + result);
126                     off += result;
127                     len -= result;
128                 }
129             }
130         }
131     }
132
133     ByteArrayOutputStream baos = new ByteArrayOutputStream();
134     protected void flush() {
135         byte[] bytes = baos.toByteArray();
136         baos = new ByteArrayOutputStream();
137         dbang(bytes, bytes.length);
138     }
139     public boolean buffered = false;
140     public void buffered() { buffered = true; }
141     public void buffered(boolean buf) { buffered = buf; }
142     public void config(int dat) { config(dat, 8); }
143     public void config(int dat, int numbits) {
144         for(int i=(numbits-1); i>=0; i--) {
145             boolean bit = (dat & (1<<i)) != 0;
146             data(bit);
147             clk(true);
148             clk(false);
149         }
150     }
151
152     public void reset(boolean on) {
153         bits = on ? (1<<1) : 0;
154         cbangmode();
155         //dbang(0, on);
156     }
157     public void avrrst(boolean on) {
158         dbang(7, on);
159     }
160     public boolean initErr() { return (readPins() & (1<<4))!=0; }
161     public void clk(boolean on) { dbang(6, on); }
162     public void data(boolean on) { dbang(5, on); }
163
164     public boolean con() {
165
166         /*
167         mask &= ~(1<<0);
168         cbangmode();
169         boolean ret = (readPins() & (1<<0)) != 0;
170         dbangmode();
171         return ret;
172         */
173
174
175
176         dmask &= ~(1<<0);
177         dbangmode();
178         return (readPins() & (1<<0)) != 0;
179
180     }
181     public void con(boolean on) {
182
183         /*
184         mask |= (1<<0);
185         bits = on ? (1<<0) : 0;
186         cbangmode();
187         */
188
189
190         dmask |= (1<<0);
191         dbangmode();
192         dbang(0, on);
193
194     }
195
196     private static int mask =
197         (1<<0) |
198         (1<<1)// |
199         //(1<<2) |
200         //(1<<3)
201         ;
202
203     private static int dmask =
204         //(1<<0) |
205
206         (1<<1) |
207         (1<<2) |
208
209         //(1<<3) |
210         //(1<<4) |
211         (1<<5) |
212         (1<<6) |
213         (1<<7);
214
215     public synchronized void purge() {
216         example.ftdi_usb_purge_buffers(context);
217
218         int result = example.ftdi_setflowctrl(context, (1 << 8));
219         if (result != 0)
220             throw new RuntimeException("ftdi_setflowcontrol() returned " +
221                                        result);
222     }
223     public synchronized void uart() {
224         int result = example.ftdi_set_bitmode(context, (short)0, (short)0x00);
225         if (result != 0)
226             throw new RuntimeException("ftdi_set_bitmode() returned " + result);
227
228         result = example.ftdi_setflowctrl(context, (1 << 8));
229         if (result != 0)
230             throw new RuntimeException("ftdi_setflowcontrol() returned " +
231                                        result);
232
233     }
234     public synchronized void dbangmode() {
235         int result = example.ftdi_set_bitmode(context, (short)dmask, (short)0x01);
236         if (result != 0)
237             throw new RuntimeException("ftdi_set_bitmode() returned " + result);
238     }
239
240     private synchronized void cbangmode() {
241         int result = example.ftdi_set_bitmode(context, (short)((mask << 4) | bits), (short)0x20);
242         if (result != 0)
243             throw new RuntimeException("ftdi_set_bitmode() returned " + result);
244     }
245
246     private int dbits = 0;
247     private synchronized void dbang(int bit, boolean val) {
248         dbits = val ? (dbits | (1 << bit)) : (dbits & (~(1 << bit)));
249         if (buffered) {
250             baos.write((byte)dbits);
251         } else {
252             dbang((byte)dbits);
253         }
254     }
255     int write = 0;
256     private synchronized void dbang(byte by) {
257         byte[] b = new byte[1];
258         b[0] = by;
259         int result = example.ftdi_write_data(context, b, 1);
260         if (result != 1)
261             throw new RuntimeException("ftdi_write_data() returned " + result);
262     }
263     int queued = 0;
264     private synchronized void dbang(byte[] b, int len) {
265         example.ftdi_write_data(context, b, len);
266     }
267 }