5 * A Java wrapper around libftdi.
7 * Note: blocking reads are currently implemented by busy-waiting.
8 * This is really ugly. Check the linux kernel source to see how to
9 * get libftdi to do it properly.
11 public class FtdiUart {
15 File f = new File("build/"+System.mapLibraryName("FtdiUartNative"));
16 if (f.exists()) System.load(f.getAbsolutePath());
17 else System.loadLibrary("FtdiUartNative");
18 } catch (Exception e) {
19 throw new RuntimeException();
23 private SWIGTYPE_p_ftdi_context context = FtdiUartNative.new_ftdi_context();
25 public FtdiUart(int vendorId, int productId, int baud) throws IOException {
26 FtdiUartNative.ftdi_init(context);
27 FtdiUartNative.ftdi_usb_open(context, vendorId, productId);
28 FtdiUartNative.ftdi_usb_reset(context);
29 FtdiUartNative.ftdi_set_baudrate(context, baud);
30 FtdiUartNative.ftdi_set_line_property(context, 8, 0, 0);
31 FtdiUartNative.ftdi_setflowctrl(context, (1<<8));
35 /** the output stream to the uart or dbus pins (depending on mode) */
36 public OutputStream getOutputStream() { return out; }
38 /** the input stream from the uart or dbus pins (depending on mode) */
39 public InputStream getInputStream() { return in; }
42 * Switch to uart mode, with read/write access to four CBUS lines.
43 * This function is used to write to the CBUS lines (re-invoke it to change their state).
44 * I think readPins() is used to read from them, but I'm not sure.
46 * @param cbus_mask a four-bit mask; set bit=1 to write to a CBUS line, bit=0 to read from it
47 * @param cbus_bits a four-bit mask; the bits to assert on the write-enabled CBUS lines
49 public synchronized void uart_and_cbus_mode(int cbus_mask, int cbus_bits) throws IOException {
50 FtdiUartNative.ftdi_set_bitmode(context, (short)((cbus_mask << 4) | cbus_bits), (short)0x20);
51 FtdiUartNative.ftdi_setflowctrl(context, (1<<8));
55 * Switch to dbus mode; CBUS lines will be released (ie they will float).
56 * Use getInputStream()/getOutputStream() to read/write the eight DBUS lines.
58 * @param dbus_mask an eight-bit mask; set bit=1 to write to a DBUS line, bit=0 to read from it
60 public synchronized void dbus_mode(int dbus_mask) throws IOException {
61 FtdiUartNative.ftdi_set_bitmode(context, (short)dbus_mask, (short)0x01);
64 public synchronized void setBitRate(int bitRate) throws IOException {
65 FtdiUartNative.ftdi_set_baudrate(context, bitRate);
68 /** returns the instantaneous value present on the DBUS pins */
69 public synchronized int readPins() throws IOException {
70 getOutputStream().flush();
71 byte[] b = new byte[1];
72 FtdiUartNative.ftdi_read_pins(context, b);
76 /** purge the on-chip buffers */
77 public synchronized void purge() throws IOException {
78 FtdiUartNative.ftdi_usb_purge_buffers(context);
81 private final InputStream in = new InputStream() {
82 public int available() throws IOException {
86 public int read() throws IOException {
87 byte[] b = new byte[1];
89 while(result==0) result = read(b, 0, 1);
92 public int read(byte[] b, int off, int len) throws IOException {
93 // FIXME: blocking reads?
97 byte[] b0 = new byte[len];
98 synchronized(FtdiUart.this) {
99 result = FtdiUartNative.ftdi_read_data(context, b0, len);
102 System.arraycopy(b0, 0, b, off, result);
105 try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); }
110 private final OutputStream out = new BufferedOutputStream(new OutputStream() {
111 public void write(int b) throws IOException {
112 byte[] d = new byte[1];
116 public void write(byte[] b, int off, int len) throws IOException {
117 byte[] b2 = new byte[64];
119 System.arraycopy(b, off, b2, 0, Math.min(b2.length, len));
121 synchronized(FtdiUart.this) {
122 result = FtdiUartNative.ftdi_write_data(context, b2, Math.min(b2.length, len));