mirror of
https://github.com/mik3y/usb-serial-for-android.git
synced 2026-08-16 02:43:11 +00:00
support ft_232h, cp210_ multiport devices
harmonize claimInterface() error handling cancel read() on close()
This commit is contained in:
+13
-7
@@ -84,9 +84,10 @@ public class Ch34xSerialDriver implements UsbSerialDriver {
|
||||
private boolean dtr = false;
|
||||
private boolean rts = false;
|
||||
|
||||
private final boolean mEnableAsyncReads;
|
||||
private final Boolean mEnableAsyncReads;
|
||||
private UsbEndpoint mReadEndpoint;
|
||||
private UsbEndpoint mWriteEndpoint;
|
||||
private UsbRequest mUsbRequest;
|
||||
|
||||
public Ch340SerialPort(UsbDevice device, int portNumber) {
|
||||
super(device, portNumber);
|
||||
@@ -109,10 +110,8 @@ public class Ch34xSerialDriver implements UsbSerialDriver {
|
||||
try {
|
||||
for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
|
||||
UsbInterface usbIface = mDevice.getInterface(i);
|
||||
if (mConnection.claimInterface(usbIface, true)) {
|
||||
Log.d(TAG, "claimInterface " + i + " SUCCESS");
|
||||
} else {
|
||||
Log.d(TAG, "claimInterface " + i + " FAIL");
|
||||
if (!mConnection.claimInterface(usbIface, true)) {
|
||||
throw new IOException("Could not claim data interface.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,7 +153,10 @@ public class Ch34xSerialDriver implements UsbSerialDriver {
|
||||
if (mConnection == null) {
|
||||
throw new IOException("Already closed");
|
||||
}
|
||||
|
||||
synchronized (mEnableAsyncReads) {
|
||||
if (mUsbRequest != null)
|
||||
mUsbRequest.cancel();
|
||||
}
|
||||
// TODO: nothing sended on close, maybe needed?
|
||||
|
||||
try {
|
||||
@@ -175,8 +177,11 @@ public class Ch34xSerialDriver implements UsbSerialDriver {
|
||||
if (!request.queue(buf, dest.length)) {
|
||||
throw new IOException("Error queueing request.");
|
||||
}
|
||||
|
||||
mUsbRequest = request;
|
||||
final UsbRequest response = mConnection.requestWait();
|
||||
synchronized (mEnableAsyncReads) {
|
||||
mUsbRequest = null;
|
||||
}
|
||||
if (response == null) {
|
||||
throw new IOException("Null response");
|
||||
}
|
||||
@@ -189,6 +194,7 @@ public class Ch34xSerialDriver implements UsbSerialDriver {
|
||||
return 0;
|
||||
}
|
||||
} finally {
|
||||
mUsbRequest = null;
|
||||
request.close();
|
||||
}
|
||||
} else {
|
||||
|
||||
+44
-17
@@ -32,7 +32,7 @@ import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Collections;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -42,11 +42,14 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
|
||||
private static final String TAG = Cp21xxSerialDriver.class.getSimpleName();
|
||||
|
||||
private final UsbDevice mDevice;
|
||||
private final UsbSerialPort mPort;
|
||||
private final List<UsbSerialPort> mPorts;
|
||||
|
||||
public Cp21xxSerialDriver(UsbDevice device) {
|
||||
mDevice = device;
|
||||
mPort = new Cp21xxSerialPort(mDevice, 0);
|
||||
mPorts = new ArrayList<>();
|
||||
for( int port = 0; port < device.getInterfaceCount(); port++) {
|
||||
mPorts.add(new Cp21xxSerialPort(mDevice, port));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -56,7 +59,7 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
|
||||
|
||||
@Override
|
||||
public List<UsbSerialPort> getPorts() {
|
||||
return Collections.singletonList(mPort);
|
||||
return mPorts;
|
||||
}
|
||||
|
||||
public class Cp21xxSerialPort extends CommonUsbSerialPort {
|
||||
@@ -104,9 +107,14 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
|
||||
private static final int CONTROL_WRITE_DTR = 0x0100;
|
||||
private static final int CONTROL_WRITE_RTS = 0x0200;
|
||||
|
||||
private final boolean mEnableAsyncReads;
|
||||
private final Boolean mEnableAsyncReads;
|
||||
private UsbEndpoint mReadEndpoint;
|
||||
private UsbEndpoint mWriteEndpoint;
|
||||
private UsbRequest mUsbRequest;
|
||||
|
||||
// second port of Cp2105 has limited baudRate, dataBits, stopBits, parity
|
||||
// unsupported baudrate returns error at controlTransfer(), other parameters are silently ignored
|
||||
private boolean mIsRestrictedPort;
|
||||
|
||||
public Cp21xxSerialPort(UsbDevice device, int portNumber) {
|
||||
super(device, portNumber);
|
||||
@@ -120,7 +128,7 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
|
||||
|
||||
private int setConfigSingle(int request, int value) {
|
||||
return mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, request, value,
|
||||
0, null, 0, USB_WRITE_TIMEOUT_MILLIS);
|
||||
mPortNumber, null, 0, USB_WRITE_TIMEOUT_MILLIS);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -131,17 +139,15 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
|
||||
|
||||
mConnection = connection;
|
||||
boolean opened = false;
|
||||
mIsRestrictedPort = mDevice.getInterfaceCount() == 2 && mPortNumber == 1;
|
||||
try {
|
||||
for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
|
||||
UsbInterface usbIface = mDevice.getInterface(i);
|
||||
if (mConnection.claimInterface(usbIface, true)) {
|
||||
Log.d(TAG, "claimInterface " + i + " SUCCESS");
|
||||
} else {
|
||||
Log.d(TAG, "claimInterface " + i + " FAIL");
|
||||
}
|
||||
if(mPortNumber >= mDevice.getInterfaceCount()) {
|
||||
throw new IOException("Unknown port number");
|
||||
}
|
||||
UsbInterface dataIface = mDevice.getInterface(mPortNumber);
|
||||
if (!mConnection.claimInterface(dataIface, true)) {
|
||||
throw new IOException("Could not claim interface " + mPortNumber);
|
||||
}
|
||||
|
||||
UsbInterface dataIface = mDevice.getInterface(mDevice.getInterfaceCount() - 1);
|
||||
for (int i = 0; i < dataIface.getEndpointCount(); i++) {
|
||||
UsbEndpoint ep = dataIface.getEndpoint(i);
|
||||
if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
|
||||
@@ -174,6 +180,11 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
|
||||
if (mConnection == null) {
|
||||
throw new IOException("Already closed");
|
||||
}
|
||||
synchronized (mEnableAsyncReads) {
|
||||
if(mUsbRequest != null) {
|
||||
mUsbRequest.cancel();
|
||||
}
|
||||
}
|
||||
try {
|
||||
setConfigSingle(SILABSER_IFC_ENABLE_REQUEST_CODE, UART_DISABLE);
|
||||
mConnection.close();
|
||||
@@ -192,8 +203,11 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
|
||||
if (!request.queue(buf, dest.length)) {
|
||||
throw new IOException("Error queueing request.");
|
||||
}
|
||||
|
||||
mUsbRequest = request;
|
||||
final UsbRequest response = mConnection.requestWait();
|
||||
synchronized (mEnableAsyncReads) {
|
||||
mUsbRequest = null;
|
||||
}
|
||||
if (response == null) {
|
||||
throw new IOException("Null response");
|
||||
}
|
||||
@@ -206,6 +220,7 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
|
||||
return 0;
|
||||
}
|
||||
} finally {
|
||||
mUsbRequest = null;
|
||||
request.close();
|
||||
}
|
||||
} else {
|
||||
@@ -269,7 +284,7 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
|
||||
(byte) ((baudRate >> 24) & 0xff)
|
||||
};
|
||||
int ret = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, SILABSER_SET_BAUDRATE,
|
||||
0, 0, data, 4, USB_WRITE_TIMEOUT_MILLIS);
|
||||
0, mPortNumber, data, 4, USB_WRITE_TIMEOUT_MILLIS);
|
||||
if (ret < 0) {
|
||||
throw new IOException("Error setting baud rate.");
|
||||
}
|
||||
@@ -283,12 +298,18 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
|
||||
int configDataBits = 0;
|
||||
switch (dataBits) {
|
||||
case DATABITS_5:
|
||||
if(mIsRestrictedPort)
|
||||
throw new IllegalArgumentException("Unsupported dataBits value: " + dataBits);
|
||||
configDataBits |= 0x0500;
|
||||
break;
|
||||
case DATABITS_6:
|
||||
if(mIsRestrictedPort)
|
||||
throw new IllegalArgumentException("Unsupported dataBits value: " + dataBits);
|
||||
configDataBits |= 0x0600;
|
||||
break;
|
||||
case DATABITS_7:
|
||||
if(mIsRestrictedPort)
|
||||
throw new IllegalArgumentException("Unsupported dataBits value: " + dataBits);
|
||||
configDataBits |= 0x0700;
|
||||
break;
|
||||
case DATABITS_8:
|
||||
@@ -308,9 +329,13 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
|
||||
configDataBits |= 0x0020;
|
||||
break;
|
||||
case PARITY_MARK:
|
||||
if(mIsRestrictedPort)
|
||||
throw new IllegalArgumentException("Unsupported parity value: mark");
|
||||
configDataBits |= 0x0030;
|
||||
break;
|
||||
case PARITY_SPACE:
|
||||
if(mIsRestrictedPort)
|
||||
throw new IllegalArgumentException("Unsupported parity value: space");
|
||||
configDataBits |= 0x0040;
|
||||
break;
|
||||
default:
|
||||
@@ -323,6 +348,8 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
|
||||
case STOPBITS_1_5:
|
||||
throw new IllegalArgumentException("Unsupported stopBits value: 1.5");
|
||||
case STOPBITS_2:
|
||||
if(mIsRestrictedPort)
|
||||
throw new IllegalArgumentException("Unsupported stopBits value: 2");
|
||||
configDataBits |= 2;
|
||||
break;
|
||||
default:
|
||||
|
||||
+36
-29
@@ -29,11 +29,9 @@ import android.hardware.usb.UsbRequest;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
import com.hoho.android.usbserial.util.HexDump;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Collections;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -73,6 +71,8 @@ import java.util.Map;
|
||||
* Supported and tested devices:
|
||||
* <ul>
|
||||
* <li>{@value DeviceType#TYPE_R}</li>
|
||||
* <li>{@value DeviceType#TYPE_2232H}</li>
|
||||
* <li>{@value DeviceType#TYPE_4232H}</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
* <p>
|
||||
@@ -80,8 +80,6 @@ import java.util.Map;
|
||||
* feedback or patches):
|
||||
* <ul>
|
||||
* <li>{@value DeviceType#TYPE_2232C}</li>
|
||||
* <li>{@value DeviceType#TYPE_2232H}</li>
|
||||
* <li>{@value DeviceType#TYPE_4232H}</li>
|
||||
* <li>{@value DeviceType#TYPE_AM}</li>
|
||||
* <li>{@value DeviceType#TYPE_BM}</li>
|
||||
* </ul>
|
||||
@@ -96,7 +94,7 @@ import java.util.Map;
|
||||
public class FtdiSerialDriver implements UsbSerialDriver {
|
||||
|
||||
private final UsbDevice mDevice;
|
||||
private final UsbSerialPort mPort;
|
||||
private final List<UsbSerialPort> mPorts;
|
||||
|
||||
/**
|
||||
* FTDI chip types.
|
||||
@@ -107,8 +105,12 @@ public class FtdiSerialDriver implements UsbSerialDriver {
|
||||
|
||||
public FtdiSerialDriver(UsbDevice device) {
|
||||
mDevice = device;
|
||||
mPort = new FtdiSerialPort(mDevice, 0);
|
||||
mPorts = new ArrayList<>();
|
||||
for( int port = 0; port < device.getInterfaceCount(); port++) {
|
||||
mPorts.add(new FtdiSerialPort(mDevice, port));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UsbDevice getDevice() {
|
||||
return mDevice;
|
||||
@@ -116,7 +118,7 @@ public class FtdiSerialDriver implements UsbSerialDriver {
|
||||
|
||||
@Override
|
||||
public List<UsbSerialPort> getPorts() {
|
||||
return Collections.singletonList(mPort);
|
||||
return mPorts;
|
||||
}
|
||||
|
||||
private class FtdiSerialPort extends CommonUsbSerialPort {
|
||||
@@ -182,9 +184,7 @@ public class FtdiSerialDriver implements UsbSerialDriver {
|
||||
|
||||
private DeviceType mType;
|
||||
|
||||
private int mInterface = 0; /* INTERFACE_ANY */
|
||||
|
||||
private int mMaxPacketSize = 64; // TODO(mikey): detect
|
||||
private int mIndex = 0;
|
||||
|
||||
/**
|
||||
* Due to http://b.android.com/28023 , we cannot use UsbRequest async reads
|
||||
@@ -230,14 +230,21 @@ public class FtdiSerialDriver implements UsbSerialDriver {
|
||||
}
|
||||
|
||||
public void reset() throws IOException {
|
||||
// TODO(mikey): autodetect.
|
||||
mType = DeviceType.TYPE_R;
|
||||
if(mDevice.getInterfaceCount() > 1) {
|
||||
mIndex = mPortNumber + 1;
|
||||
if (mDevice.getInterfaceCount() == 2)
|
||||
mType = DeviceType.TYPE_2232H;
|
||||
if (mDevice.getInterfaceCount() == 4)
|
||||
mType = DeviceType.TYPE_4232H;
|
||||
}
|
||||
|
||||
int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE, SIO_RESET_REQUEST,
|
||||
SIO_RESET_SIO, 0 /* index */, null, 0, USB_WRITE_TIMEOUT_MILLIS);
|
||||
SIO_RESET_SIO, mIndex, null, 0, USB_WRITE_TIMEOUT_MILLIS);
|
||||
if (result != 0) {
|
||||
throw new IOException("Reset failed: result=" + result);
|
||||
}
|
||||
|
||||
// TODO(mikey): autodetect.
|
||||
mType = DeviceType.TYPE_R;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -249,12 +256,10 @@ public class FtdiSerialDriver implements UsbSerialDriver {
|
||||
|
||||
boolean opened = false;
|
||||
try {
|
||||
for (int i = 0; i < mDevice.getInterfaceCount(); i++) {
|
||||
if (connection.claimInterface(mDevice.getInterface(i), true)) {
|
||||
Log.d(TAG, "claimInterface " + i + " SUCCESS");
|
||||
} else {
|
||||
throw new IOException("Error claiming interface " + i);
|
||||
}
|
||||
if (connection.claimInterface(mDevice.getInterface(mPortNumber), true)) {
|
||||
Log.d(TAG, "claimInterface " + mPortNumber + " SUCCESS");
|
||||
} else {
|
||||
throw new IOException("Error claiming interface " + mPortNumber);
|
||||
}
|
||||
reset();
|
||||
opened = true;
|
||||
@@ -280,7 +285,7 @@ public class FtdiSerialDriver implements UsbSerialDriver {
|
||||
|
||||
@Override
|
||||
public int read(byte[] dest, int timeoutMillis) throws IOException {
|
||||
final UsbEndpoint endpoint = mDevice.getInterface(0).getEndpoint(0);
|
||||
final UsbEndpoint endpoint = mDevice.getInterface(mPortNumber).getEndpoint(0);
|
||||
|
||||
if (mEnableAsyncReads) {
|
||||
final UsbRequest request = new UsbRequest();
|
||||
@@ -325,7 +330,7 @@ public class FtdiSerialDriver implements UsbSerialDriver {
|
||||
|
||||
@Override
|
||||
public int write(byte[] src, int timeoutMillis) throws IOException {
|
||||
final UsbEndpoint endpoint = mDevice.getInterface(0).getEndpoint(1);
|
||||
final UsbEndpoint endpoint = mDevice.getInterface(mPortNumber).getEndpoint(1);
|
||||
int offset = 0;
|
||||
|
||||
while (offset < src.length) {
|
||||
@@ -425,7 +430,7 @@ public class FtdiSerialDriver implements UsbSerialDriver {
|
||||
}
|
||||
|
||||
int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE,
|
||||
SIO_SET_DATA_REQUEST, config, 0 /* index */,
|
||||
SIO_SET_DATA_REQUEST, config, mIndex,
|
||||
null, 0, USB_WRITE_TIMEOUT_MILLIS);
|
||||
if (result != 0) {
|
||||
throw new IOException("Setting parameters failed: result=" + result);
|
||||
@@ -505,9 +510,8 @@ public class FtdiSerialDriver implements UsbSerialDriver {
|
||||
long index;
|
||||
if (mType == DeviceType.TYPE_2232C || mType == DeviceType.TYPE_2232H
|
||||
|| mType == DeviceType.TYPE_4232H) {
|
||||
index = (encodedDivisor >> 8) & 0xffff;
|
||||
index &= 0xFF00;
|
||||
index |= 0 /* TODO mIndex */;
|
||||
index = (encodedDivisor >> 8) & 0xff00;
|
||||
index |= mIndex;
|
||||
} else {
|
||||
index = (encodedDivisor >> 16) & 0xffff;
|
||||
}
|
||||
@@ -560,7 +564,7 @@ public class FtdiSerialDriver implements UsbSerialDriver {
|
||||
public boolean purgeHwBuffers(boolean purgeReadBuffers, boolean purgeWriteBuffers) throws IOException {
|
||||
if (purgeReadBuffers) {
|
||||
int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE, SIO_RESET_REQUEST,
|
||||
SIO_RESET_PURGE_RX, 0 /* index */, null, 0, USB_WRITE_TIMEOUT_MILLIS);
|
||||
SIO_RESET_PURGE_RX, mIndex, null, 0, USB_WRITE_TIMEOUT_MILLIS);
|
||||
if (result != 0) {
|
||||
throw new IOException("Flushing RX failed: result=" + result);
|
||||
}
|
||||
@@ -568,7 +572,7 @@ public class FtdiSerialDriver implements UsbSerialDriver {
|
||||
|
||||
if (purgeWriteBuffers) {
|
||||
int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE, SIO_RESET_REQUEST,
|
||||
SIO_RESET_PURGE_TX, 0 /* index */, null, 0, USB_WRITE_TIMEOUT_MILLIS);
|
||||
SIO_RESET_PURGE_TX, mIndex, null, 0, USB_WRITE_TIMEOUT_MILLIS);
|
||||
if (result != 0) {
|
||||
throw new IOException("Flushing RX failed: result=" + result);
|
||||
}
|
||||
@@ -582,6 +586,9 @@ public class FtdiSerialDriver implements UsbSerialDriver {
|
||||
supportedDevices.put(Integer.valueOf(UsbId.VENDOR_FTDI),
|
||||
new int[] {
|
||||
UsbId.FTDI_FT232R,
|
||||
UsbId.FTDI_FT232H,
|
||||
UsbId.FTDI_FT2232H,
|
||||
UsbId.FTDI_FT4232H,
|
||||
UsbId.FTDI_FT231X,
|
||||
});
|
||||
return supportedDevices;
|
||||
|
||||
@@ -33,6 +33,9 @@ public final class UsbId {
|
||||
|
||||
public static final int VENDOR_FTDI = 0x0403;
|
||||
public static final int FTDI_FT232R = 0x6001;
|
||||
public static final int FTDI_FT2232H = 0x6010;
|
||||
public static final int FTDI_FT4232H = 0x6011;
|
||||
public static final int FTDI_FT232H = 0x6014;
|
||||
public static final int FTDI_FT231X = 0x6015;
|
||||
|
||||
public static final int VENDOR_ATMEL = 0x03EB;
|
||||
|
||||
Reference in New Issue
Block a user