Update device support; change interface to abstract base class.

Adds support for Teensyduino and a few more Arduino CDC devices.
pull/36/head
mike wakerly 2012-10-10 22:52:02 -07:00
rodzic 28054ab154
commit c5e9955b01
6 zmienionych plików z 149 dodań i 49 usunięć

Wyświetl plik

@ -2,6 +2,11 @@
<resources>
<!-- 0x0403 / 0x6001: FTDI FT232R UART -->
<usb-device vendor-id="1027" product-id="24577" />
<!-- 0x2341 / 0x0001: Arduino Uno -->
<usb-device vendor-id="9025" product-id="1" />
<!-- 0x2341 / Arduino -->
<usb-device vendor-id="9025" />
<!-- 0x16C0 / 0x0483: Teensyduino -->
<usb-device vendor-id="5824" product-id="1155" />
</resources>

Wyświetl plik

@ -2,6 +2,8 @@ package com.hoho.android.usbserial.driver;
import java.io.IOException;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
@ -15,11 +17,10 @@ import android.util.Log;
*
* @author mike wakerly (opensource@hoho.com)
*/
public class CdcAcmSerialDriver implements UsbSerialDriver {
public class CdcAcmSerialDriver extends UsbSerialDriver {
private final String TAG = CdcAcmSerialDriver.class.getSimpleName();
private UsbDevice mDevice;
private UsbDeviceConnection mConnection;
private final byte[] mReadBuffer = new byte[4096];
private UsbInterface mControlInterface;
@ -29,13 +30,8 @@ public class CdcAcmSerialDriver implements UsbSerialDriver {
private UsbEndpoint mReadEndpoint;
private UsbEndpoint mWriteEndpoint;
/**
* @param usbDevice
* @param connection
*/
public CdcAcmSerialDriver(UsbDevice usbDevice, UsbDeviceConnection connection) {
mDevice = usbDevice;
mConnection = connection;
public CdcAcmSerialDriver(UsbDevice device, UsbDeviceConnection connection) {
super(device, connection);
}
@Override
@ -151,13 +147,25 @@ public class CdcAcmSerialDriver implements UsbSerialDriver {
return baudRate;
}
@Override
public UsbDevice getDevice() {
return mDevice;
}
public static boolean probe(UsbDevice usbDevice) {
return usbDevice.getVendorId() == 0x2341;
public static Map<Integer, int[]> getSupportedDevices() {
final Map<Integer, int[]> supportedDevices = new LinkedHashMap<Integer, int[]>();
supportedDevices.put(Integer.valueOf(UsbId.VENDOR_ARDUINO),
new int[] {
UsbId.ARDUINO_UNO,
UsbId.ARDUINO_UNO_R3,
UsbId.ARDUINO_MEGA_2560,
UsbId.ARDUINO_MEGA_2560_R3,
UsbId.ARDUINO_SERIAL_ADAPTER,
UsbId.ARDUINO_SERIAL_ADAPTER_R3,
UsbId.ARDUINO_MEGA_ADK,
UsbId.ARDUINO_MEGA_ADK_R3,
UsbId.ARDUINO_LEONARDO,
});
supportedDevices.put(Integer.valueOf(UsbId.VENDOR_VAN_OOIJEN_TECH),
new int[] {
UsbId.VAN_OOIJEN_TECH_TEENSYDUINO_SERIAL,
});
return supportedDevices;
}
}

Wyświetl plik

@ -20,6 +20,12 @@
package com.hoho.android.usbserial.driver;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
@ -29,10 +35,6 @@ import android.util.Log;
import com.hoho.android.usbserial.util.HexDump;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
/**
* A {@link UsbSerialDriver} implementation for a variety of FTDI devices
* <p>
@ -86,7 +88,7 @@ import java.util.Arrays;
* @see <a href="http://www.ftdichip.com/">FTDI Homepage</a>
* @see <a href="http://www.intra2net.com/en/developer/libftdi">libftdi</a>
*/
public class FtdiSerialDriver implements UsbSerialDriver {
public class FtdiSerialDriver extends UsbSerialDriver {
private static final int DEFAULT_BAUD_RATE = 115200;
@ -152,8 +154,6 @@ public class FtdiSerialDriver implements UsbSerialDriver {
private final String TAG = FtdiSerialDriver.class.getSimpleName();
private UsbDevice mDevice;
private UsbDeviceConnection mConnection;
private DeviceType mType;
private final byte[] mReadBuffer = new byte[4096];
@ -185,11 +185,7 @@ public class FtdiSerialDriver implements UsbSerialDriver {
* with this driver
*/
public FtdiSerialDriver(UsbDevice usbDevice, UsbDeviceConnection usbConnection) {
if (!probe(usbDevice)) {
throw new UsbSerialRuntimeException("Device type not supported.");
}
mConnection = usbConnection;
mDevice = usbDevice;
super(usbDevice, usbConnection);
mType = null;
}
@ -404,14 +400,13 @@ public class FtdiSerialDriver implements UsbSerialDriver {
};
}
public static boolean probe(UsbDevice usbDevice) {
// TODO(mikey): Support other devices.
return usbDevice.getVendorId() == 0x0403 && usbDevice.getProductId() == 0x6001;
}
@Override
public UsbDevice getDevice() {
return mDevice;
public static Map<Integer, int[]> getSupportedDevices() {
final Map<Integer, int[]> supportedDevices = new LinkedHashMap<Integer, int[]>();
supportedDevices.put(Integer.valueOf(UsbId.VENDOR_FTDI),
new int[] {
UsbId.FTDI_FT232R,
});
return supportedDevices;
}
}

Wyświetl plik

@ -0,0 +1,53 @@
/* Copyright 2012 Google Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* Project home page: http://code.google.com/p/usb-serial-for-android/
*/
package com.hoho.android.usbserial.driver;
/**
* Registry of USB vendor/product ID constants.
*
* Culled from various sources; see
* <a href="http://www.linux-usb.org/usb.ids">usb.ids</a> for one listing.
*
* @author mike wakerly (opensource@hoho.com)
*/
public final class UsbId {
public static final int VENDOR_FTDI = 0x0403;
public static final int FTDI_FT232R = 0x6001;
public static final int VENDOR_ARDUINO = 0x2341;
public static final int ARDUINO_UNO = 0x0001;
public static final int ARDUINO_MEGA_2560 = 0x0010;
public static final int ARDUINO_SERIAL_ADAPTER = 0x003b;
public static final int ARDUINO_MEGA_ADK = 0x003f;
public static final int ARDUINO_MEGA_2560_R3 = 0x0042;
public static final int ARDUINO_UNO_R3 = 0x0043;
public static final int ARDUINO_MEGA_ADK_R3 = 0x0044;
public static final int ARDUINO_SERIAL_ADAPTER_R3 = 0x0044;
public static final int ARDUINO_LEONARDO = 0x8036;
public static final int VENDOR_VAN_OOIJEN_TECH = 0x16c0;
public static final int VAN_OOIJEN_TECH_TEENSYDUINO_SERIAL = 0x0483;
private UsbId() {
throw new IllegalAccessError("Non-instantiable class.");
}
}

Wyświetl plik

@ -23,13 +23,22 @@ package com.hoho.android.usbserial.driver;
import java.io.IOException;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
/**
* Driver interface for a supported USB serial device.
*
* @author mike wakerly (opensource@hoho.com)
*/
public interface UsbSerialDriver {
public abstract class UsbSerialDriver {
protected final UsbDevice mDevice;
protected final UsbDeviceConnection mConnection;
public UsbSerialDriver(UsbDevice device, UsbDeviceConnection connection) {
mDevice = device;
mConnection = connection;
}
/**
* Opens and initializes the device as a USB serial device. Upon success,
@ -37,14 +46,14 @@ public interface UsbSerialDriver {
*
* @throws IOException on error opening or initializing the device.
*/
public void open() throws IOException;
public abstract void open() throws IOException;
/**
* Closes the serial device.
*
* @throws IOException on error closing the device.
*/
public void close() throws IOException;
public abstract void close() throws IOException;
/**
* Reads as many bytes as possible into the destination buffer.
@ -54,7 +63,7 @@ public interface UsbSerialDriver {
* @return the actual number of bytes read
* @throws IOException if an error occurred during reading
*/
public int read(final byte[] dest, final int timeoutMillis) throws IOException;
public abstract int read(final byte[] dest, final int timeoutMillis) throws IOException;
/**
* Writes as many bytes as possible from the source buffer.
@ -64,7 +73,7 @@ public interface UsbSerialDriver {
* @return the actual number of bytes written
* @throws IOException if an error occurred during writing
*/
public int write(final byte[] src, final int timeoutMillis) throws IOException;
public abstract int write(final byte[] src, final int timeoutMillis) throws IOException;
/**
* Sets the baud rate of the serial device.
@ -73,13 +82,15 @@ public interface UsbSerialDriver {
* @return the actual rate set
* @throws IOException on error setting the baud rate
*/
public int setBaudRate(final int baudRate) throws IOException;
public abstract int setBaudRate(final int baudRate) throws IOException;
/**
* Returns the currently-bound USB device.
*
* @return the device
*/
public UsbDevice getDevice();
public final UsbDevice getDevice() {
return mDevice;
}
}

Wyświetl plik

@ -20,6 +20,8 @@
package com.hoho.android.usbserial.driver;
import java.util.Map;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
@ -32,6 +34,8 @@ import android.hardware.usb.UsbManager;
*/
public enum UsbSerialProber {
// TODO(mikey): Too much boilerplate.
/**
* Prober for {@link FtdiSerialDriver}.
*
@ -40,7 +44,7 @@ public enum UsbSerialProber {
FTDI_SERIAL {
@Override
public UsbSerialDriver getDevice(final UsbManager manager, final UsbDevice usbDevice) {
if (!FtdiSerialDriver.probe(usbDevice)) {
if (!testIfSupported(usbDevice, FtdiSerialDriver.getSupportedDevices())) {
return null;
}
final UsbDeviceConnection connection = manager.openDevice(usbDevice);
@ -54,8 +58,8 @@ public enum UsbSerialProber {
CDC_ACM_SERIAL {
@Override
public UsbSerialDriver getDevice(UsbManager manager, UsbDevice usbDevice) {
if (!CdcAcmSerialDriver.probe(usbDevice)) {
return null;
if (!testIfSupported(usbDevice, CdcAcmSerialDriver.getSupportedDevices())) {
return null;
}
final UsbDeviceConnection connection = manager.openDevice(usbDevice);
if (connection == null) {
@ -116,4 +120,28 @@ public enum UsbSerialProber {
return null;
}
/**
* Returns {@code true} if the given device is found in the vendor/product map.
*
* @param usbDevice the device to test
* @param supportedDevices map of vendor ids to product id(s)
* @return {@code true} if supported
*/
private static boolean testIfSupported(final UsbDevice usbDevice,
final Map<Integer, int[]> supportedDevices) {
final int[] supportedProducts = supportedDevices.get(
Integer.valueOf(usbDevice.getVendorId()));
if (supportedProducts == null) {
return false;
}
final int productId = usbDevice.getProductId();
for (int supportedProductId : supportedProducts) {
if (productId == supportedProductId) {
return true;
}
}
return false;
}
}