From c5e9955b015a8de86886cb31603f326b49166a08 Mon Sep 17 00:00:00 2001 From: mike wakerly Date: Wed, 10 Oct 2012 22:52:02 -0700 Subject: [PATCH] Update device support; change interface to abstract base class. Adds support for Teensyduino and a few more Arduino CDC devices. --- UsbSerialExamples/res/xml/device_filter.xml | 9 +++- .../usbserial/driver/CdcAcmSerialDriver.java | 42 +++++++++------ .../usbserial/driver/FtdiSerialDriver.java | 35 ++++++------ .../hoho/android/usbserial/driver/UsbId.java | 53 +++++++++++++++++++ .../usbserial/driver/UsbSerialDriver.java | 25 ++++++--- .../usbserial/driver/UsbSerialProber.java | 34 ++++++++++-- 6 files changed, 149 insertions(+), 49 deletions(-) create mode 100644 UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbId.java diff --git a/UsbSerialExamples/res/xml/device_filter.xml b/UsbSerialExamples/res/xml/device_filter.xml index fabcb9a..2f1d6c4 100644 --- a/UsbSerialExamples/res/xml/device_filter.xml +++ b/UsbSerialExamples/res/xml/device_filter.xml @@ -2,6 +2,11 @@ - - + + + + + + + diff --git a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/CdcAcmSerialDriver.java b/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/CdcAcmSerialDriver.java index 495f247..b837683 100644 --- a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/CdcAcmSerialDriver.java +++ b/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/CdcAcmSerialDriver.java @@ -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 getSupportedDevices() { + final Map supportedDevices = new LinkedHashMap(); + 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; } } diff --git a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/FtdiSerialDriver.java b/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/FtdiSerialDriver.java index 9b88d2e..a739fa1 100644 --- a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/FtdiSerialDriver.java +++ b/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/FtdiSerialDriver.java @@ -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 *

@@ -86,7 +88,7 @@ import java.util.Arrays; * @see FTDI Homepage * @see libftdi */ -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 getSupportedDevices() { + final Map supportedDevices = new LinkedHashMap(); + supportedDevices.put(Integer.valueOf(UsbId.VENDOR_FTDI), + new int[] { + UsbId.FTDI_FT232R, + }); + return supportedDevices; } } diff --git a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbId.java b/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbId.java new file mode 100644 index 0000000..ed5bb76 --- /dev/null +++ b/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbId.java @@ -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 + * usb.ids 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."); + } + +} diff --git a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbSerialDriver.java b/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbSerialDriver.java index 542bc1f..6ef3ed6 100644 --- a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbSerialDriver.java +++ b/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbSerialDriver.java @@ -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; + } } diff --git a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbSerialProber.java b/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbSerialProber.java index 1ab2708..6405507 100644 --- a/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbSerialProber.java +++ b/UsbSerialLibrary/src/com/hoho/android/usbserial/driver/UsbSerialProber.java @@ -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 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; + } + }