1
0
mirror of https://github.com/mik3y/usb-serial-for-android synced 2025-06-10 01:16:27 +00:00

Update device support; change interface to abstract base class.

Adds support for Teensyduino and a few more Arduino CDC devices.
This commit is contained in:
mike wakerly 2012-10-10 22:52:02 -07:00
parent 28054ab154
commit c5e9955b01
6 changed files with 149 additions and 49 deletions

View File

@ -2,6 +2,11 @@
<resources> <resources>
<!-- 0x0403 / 0x6001: FTDI FT232R UART --> <!-- 0x0403 / 0x6001: FTDI FT232R UART -->
<usb-device vendor-id="1027" product-id="24577" /> <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> </resources>

View File

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

View File

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

View File

@ -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.");
}
}

View File

@ -23,13 +23,22 @@ package com.hoho.android.usbserial.driver;
import java.io.IOException; import java.io.IOException;
import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
/** /**
* Driver interface for a supported USB serial device. * Driver interface for a supported USB serial device.
* *
* @author mike wakerly (opensource@hoho.com) * @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, * 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. * @throws IOException on error opening or initializing the device.
*/ */
public void open() throws IOException; public abstract void open() throws IOException;
/** /**
* Closes the serial device. * Closes the serial device.
* *
* @throws IOException on error closing the 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. * Reads as many bytes as possible into the destination buffer.
@ -54,7 +63,7 @@ public interface UsbSerialDriver {
* @return the actual number of bytes read * @return the actual number of bytes read
* @throws IOException if an error occurred during reading * @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. * Writes as many bytes as possible from the source buffer.
@ -64,7 +73,7 @@ public interface UsbSerialDriver {
* @return the actual number of bytes written * @return the actual number of bytes written
* @throws IOException if an error occurred during writing * @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. * Sets the baud rate of the serial device.
@ -73,13 +82,15 @@ public interface UsbSerialDriver {
* @return the actual rate set * @return the actual rate set
* @throws IOException on error setting the baud rate * @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. * Returns the currently-bound USB device.
* *
* @return the device * @return the device
*/ */
public UsbDevice getDevice(); public final UsbDevice getDevice() {
return mDevice;
}
} }

View File

@ -20,6 +20,8 @@
package com.hoho.android.usbserial.driver; package com.hoho.android.usbserial.driver;
import java.util.Map;
import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection; import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager; import android.hardware.usb.UsbManager;
@ -32,6 +34,8 @@ import android.hardware.usb.UsbManager;
*/ */
public enum UsbSerialProber { public enum UsbSerialProber {
// TODO(mikey): Too much boilerplate.
/** /**
* Prober for {@link FtdiSerialDriver}. * Prober for {@link FtdiSerialDriver}.
* *
@ -40,7 +44,7 @@ public enum UsbSerialProber {
FTDI_SERIAL { FTDI_SERIAL {
@Override @Override
public UsbSerialDriver getDevice(final UsbManager manager, final UsbDevice usbDevice) { public UsbSerialDriver getDevice(final UsbManager manager, final UsbDevice usbDevice) {
if (!FtdiSerialDriver.probe(usbDevice)) { if (!testIfSupported(usbDevice, FtdiSerialDriver.getSupportedDevices())) {
return null; return null;
} }
final UsbDeviceConnection connection = manager.openDevice(usbDevice); final UsbDeviceConnection connection = manager.openDevice(usbDevice);
@ -54,8 +58,8 @@ public enum UsbSerialProber {
CDC_ACM_SERIAL { CDC_ACM_SERIAL {
@Override @Override
public UsbSerialDriver getDevice(UsbManager manager, UsbDevice usbDevice) { public UsbSerialDriver getDevice(UsbManager manager, UsbDevice usbDevice) {
if (!CdcAcmSerialDriver.probe(usbDevice)) { if (!testIfSupported(usbDevice, CdcAcmSerialDriver.getSupportedDevices())) {
return null; return null;
} }
final UsbDeviceConnection connection = manager.openDevice(usbDevice); final UsbDeviceConnection connection = manager.openDevice(usbDevice);
if (connection == null) { if (connection == null) {
@ -116,4 +120,28 @@ public enum UsbSerialProber {
return null; 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;
}
} }