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