kopia lustrzana https://github.com/mik3y/usb-serial-for-android
support PL2303GC/GB/GT/GL/GE/GS
see https://lore.kernel.org/linux-usb/20190213123000.4656-1-charlesyeh522@gmail.com/pull/366/head v3.4.0
rodzic
2f23bdfb6d
commit
c82cd284ae
|
@ -12,8 +12,14 @@
|
|||
<usb-device vendor-id="4292" product-id="60016" /> <!-- 0xea70: CP2105 -->
|
||||
<usb-device vendor-id="4292" product-id="60017" /> <!-- 0xea71: CP2108 -->
|
||||
|
||||
<!-- 0x067B / 0x2303: Prolific PL2303 -->
|
||||
<usb-device vendor-id="1659" product-id="8963" />
|
||||
<!-- 0x067B / 0x23?3: Prolific PL2303x -->
|
||||
<usb-device vendor-id="1659" product-id="8963" /> <!-- 0x2303: PL2303HX, HXD, TA, ... -->
|
||||
<usb-device vendor-id="1659" product-id="9123" /> <!-- 0x23a3: PL2303GC -->
|
||||
<usb-device vendor-id="1659" product-id="9139" /> <!-- 0x23b3: PL2303GB -->
|
||||
<usb-device vendor-id="1659" product-id="9155" /> <!-- 0x23c3: PL2303GT -->
|
||||
<usb-device vendor-id="1659" product-id="9171" /> <!-- 0x23d3: PL2303GL -->
|
||||
<usb-device vendor-id="1659" product-id="9187" /> <!-- 0x23e3: PL2303GE -->
|
||||
<usb-device vendor-id="1659" product-id="9203" /> <!-- 0x23f3: PL2303GS -->
|
||||
|
||||
<!-- 0x1a86 / 0x?523: Qinheng CH34x -->
|
||||
<usb-device vendor-id="6790" product-id="21795" /> <!-- 0x5523: CH341A -->
|
||||
|
|
|
@ -323,6 +323,7 @@ public class DeviceTest {
|
|||
403200, 460800, 614400, 806400, 921600, 1228800, 2457600, 3000000, /*6000000*/
|
||||
};
|
||||
usb.open();
|
||||
Assume.assumeFalse("only for non PL2303G*", ProlificWrapper.isDeviceTypeHxn(usb.serialPort)); // HXN does not use divisor
|
||||
|
||||
int minBaudRate = ProlificWrapper.isDeviceTypeT(usb.serialPort) ? 6 : 46;
|
||||
try {
|
||||
|
@ -1675,7 +1676,7 @@ public class DeviceTest {
|
|||
|
||||
@Test
|
||||
/* test not done by RFC2217 server. Instead output control lines are connected to
|
||||
input control lines with a binary decoder 74LS138, 74LS139, 74HC... or ...
|
||||
input control lines with a binary decoder 74LS42, 74LS138, 74LS139, 74HC... or ...
|
||||
in
|
||||
A0 = RTS
|
||||
A1 = DTR
|
||||
|
|
|
@ -5,4 +5,9 @@ public class ProlificWrapper {
|
|||
ProlificSerialDriver.ProlificSerialPort prolificSerialPort = (ProlificSerialDriver.ProlificSerialPort) serialPort;
|
||||
return prolificSerialPort.mDeviceType == ProlificSerialDriver.DeviceType.DEVICE_TYPE_T;
|
||||
}
|
||||
|
||||
public static boolean isDeviceTypeHxn(UsbSerialPort serialPort) {
|
||||
ProlificSerialDriver.ProlificSerialPort prolificSerialPort = (ProlificSerialDriver.ProlificSerialPort) serialPort;
|
||||
return prolificSerialPort.mDeviceType == ProlificSerialDriver.DeviceType.DEVICE_TYPE_HXN;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ public class ProlificSerialDriver implements UsbSerialDriver {
|
|||
28800, 38400, 57600, 115200, 128000, 134400, 161280, 201600, 230400, 268800,
|
||||
403200, 460800, 614400, 806400, 921600, 1228800, 2457600, 3000000, 6000000
|
||||
};
|
||||
protected enum DeviceType { DEVICE_TYPE_01, DEVICE_TYPE_T, DEVICE_TYPE_HX}
|
||||
protected enum DeviceType { DEVICE_TYPE_01, DEVICE_TYPE_T, DEVICE_TYPE_HX, DEVICE_TYPE_HXN}
|
||||
|
||||
private final UsbDevice mDevice;
|
||||
private final UsbSerialPort mPort;
|
||||
|
@ -62,34 +62,50 @@ public class ProlificSerialDriver implements UsbSerialDriver {
|
|||
|
||||
private static final int USB_RECIP_INTERFACE = 0x01;
|
||||
|
||||
private static final int PROLIFIC_VENDOR_READ_REQUEST = 0x01;
|
||||
private static final int PROLIFIC_VENDOR_WRITE_REQUEST = 0x01;
|
||||
private static final int VENDOR_READ_REQUEST = 0x01;
|
||||
private static final int VENDOR_WRITE_REQUEST = 0x01;
|
||||
private static final int VENDOR_READ_HXN_REQUEST = 0x81;
|
||||
private static final int VENDOR_WRITE_HXN_REQUEST = 0x80;
|
||||
|
||||
private static final int PROLIFIC_VENDOR_OUT_REQTYPE = UsbConstants.USB_DIR_OUT | UsbConstants.USB_TYPE_VENDOR;
|
||||
private static final int PROLIFIC_VENDOR_IN_REQTYPE = UsbConstants.USB_DIR_IN | UsbConstants.USB_TYPE_VENDOR;
|
||||
private static final int PROLIFIC_CTRL_OUT_REQTYPE = UsbConstants.USB_DIR_OUT | UsbConstants.USB_TYPE_CLASS | USB_RECIP_INTERFACE;
|
||||
private static final int VENDOR_OUT_REQTYPE = UsbConstants.USB_DIR_OUT | UsbConstants.USB_TYPE_VENDOR;
|
||||
private static final int VENDOR_IN_REQTYPE = UsbConstants.USB_DIR_IN | UsbConstants.USB_TYPE_VENDOR;
|
||||
private static final int CTRL_OUT_REQTYPE = UsbConstants.USB_DIR_OUT | UsbConstants.USB_TYPE_CLASS | USB_RECIP_INTERFACE;
|
||||
|
||||
private static final int WRITE_ENDPOINT = 0x02;
|
||||
private static final int READ_ENDPOINT = 0x83;
|
||||
private static final int INTERRUPT_ENDPOINT = 0x81;
|
||||
|
||||
private static final int FLUSH_RX_REQUEST = 0x08; // RX @ Prolific device = write @ usb-serial-for-android library
|
||||
private static final int RESET_HXN_REQUEST = 0x07;
|
||||
private static final int FLUSH_RX_REQUEST = 0x08;
|
||||
private static final int FLUSH_TX_REQUEST = 0x09;
|
||||
|
||||
private static final int SET_LINE_REQUEST = 0x20; // same as CDC SET_LINE_CODING
|
||||
private static final int SET_CONTROL_REQUEST = 0x22; // same as CDC SET_CONTROL_LINE_STATE
|
||||
private static final int SEND_BREAK_REQUEST = 0x23; // same as CDC SEND_BREAK
|
||||
private static final int GET_CONTROL_HXN_REQUEST = 0x80;
|
||||
private static final int GET_CONTROL_REQUEST = 0x87;
|
||||
private static final int STATUS_NOTIFICATION = 0xa1; // similar to CDC SERIAL_STATE but different length
|
||||
|
||||
/* RESET_HXN_REQUEST */
|
||||
private static final int RESET_HXN_RX_PIPE = 1;
|
||||
private static final int RESET_HXN_TX_PIPE = 2;
|
||||
|
||||
/* SET_CONTROL_REQUEST */
|
||||
private static final int CONTROL_DTR = 0x01;
|
||||
private static final int CONTROL_RTS = 0x02;
|
||||
|
||||
/* GET_CONTROL_REQUEST */
|
||||
private static final int GET_CONTROL_FLAG_CD = 0x02;
|
||||
private static final int GET_CONTROL_FLAG_DSR = 0x04;
|
||||
private static final int GET_CONTROL_FLAG_RI = 0x01;
|
||||
private static final int GET_CONTROL_FLAG_CTS = 0x08;
|
||||
|
||||
/* GET_CONTROL_HXN_REQUEST */
|
||||
private static final int GET_CONTROL_HXN_FLAG_CD = 0x40;
|
||||
private static final int GET_CONTROL_HXN_FLAG_DSR = 0x20;
|
||||
private static final int GET_CONTROL_HXN_FLAG_RI = 0x80;
|
||||
private static final int GET_CONTROL_HXN_FLAG_CTS = 0x08;
|
||||
|
||||
/* interrupt endpoint read */
|
||||
private static final int STATUS_FLAG_CD = 0x01;
|
||||
private static final int STATUS_FLAG_DSR = 0x02;
|
||||
private static final int STATUS_FLAG_RI = 0x08;
|
||||
|
@ -137,11 +153,13 @@ public class ProlificSerialDriver implements UsbSerialDriver {
|
|||
}
|
||||
|
||||
private byte[] vendorIn(int value, int index, int length) throws IOException {
|
||||
return inControlTransfer(PROLIFIC_VENDOR_IN_REQTYPE, PROLIFIC_VENDOR_READ_REQUEST, value, index, length);
|
||||
int request = (mDeviceType == DeviceType.DEVICE_TYPE_HXN) ? VENDOR_READ_HXN_REQUEST : VENDOR_READ_REQUEST;
|
||||
return inControlTransfer(VENDOR_IN_REQTYPE, request, value, index, length);
|
||||
}
|
||||
|
||||
private void vendorOut(int value, int index, byte[] data) throws IOException {
|
||||
outControlTransfer(PROLIFIC_VENDOR_OUT_REQTYPE, PROLIFIC_VENDOR_WRITE_REQUEST, value, index, data);
|
||||
int request = (mDeviceType == DeviceType.DEVICE_TYPE_HXN) ? VENDOR_WRITE_HXN_REQUEST : VENDOR_WRITE_REQUEST;
|
||||
outControlTransfer(VENDOR_OUT_REQTYPE, request, value, index, data);
|
||||
}
|
||||
|
||||
private void resetDevice() throws IOException {
|
||||
|
@ -149,10 +167,21 @@ public class ProlificSerialDriver implements UsbSerialDriver {
|
|||
}
|
||||
|
||||
private void ctrlOut(int request, int value, int index, byte[] data) throws IOException {
|
||||
outControlTransfer(PROLIFIC_CTRL_OUT_REQTYPE, request, value, index, data);
|
||||
outControlTransfer(CTRL_OUT_REQTYPE, request, value, index, data);
|
||||
}
|
||||
|
||||
private boolean testHxStatus() {
|
||||
try {
|
||||
inControlTransfer(VENDOR_IN_REQTYPE, VENDOR_READ_REQUEST, 0x8080, 0, 1);
|
||||
return true;
|
||||
} catch(IOException ignored) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void doBlackMagic() throws IOException {
|
||||
if (mDeviceType == DeviceType.DEVICE_TYPE_HXN)
|
||||
return;
|
||||
vendorIn(0x8484, 0, 1);
|
||||
vendorOut(0x0404, 0, null);
|
||||
vendorIn(0x8484, 0, 1);
|
||||
|
@ -199,12 +228,20 @@ public class ProlificSerialDriver implements UsbSerialDriver {
|
|||
if ((mReadStatusThread == null) && (mReadStatusException == null)) {
|
||||
synchronized (mReadStatusThreadLock) {
|
||||
if (mReadStatusThread == null) {
|
||||
byte[] data = vendorIn(GET_CONTROL_REQUEST, 0, 1);
|
||||
mStatus = 0;
|
||||
if((data[0] & GET_CONTROL_FLAG_CTS) == 0) mStatus |= STATUS_FLAG_CTS;
|
||||
if((data[0] & GET_CONTROL_FLAG_DSR) == 0) mStatus |= STATUS_FLAG_DSR;
|
||||
if((data[0] & GET_CONTROL_FLAG_CD) == 0) mStatus |= STATUS_FLAG_CD;
|
||||
if((data[0] & GET_CONTROL_FLAG_RI) == 0) mStatus |= STATUS_FLAG_RI;
|
||||
if(mDeviceType == DeviceType.DEVICE_TYPE_HXN) {
|
||||
byte[] data = vendorIn(GET_CONTROL_HXN_REQUEST, 0, 1);
|
||||
if ((data[0] & GET_CONTROL_HXN_FLAG_CTS) == 0) mStatus |= STATUS_FLAG_CTS;
|
||||
if ((data[0] & GET_CONTROL_HXN_FLAG_DSR) == 0) mStatus |= STATUS_FLAG_DSR;
|
||||
if ((data[0] & GET_CONTROL_HXN_FLAG_CD) == 0) mStatus |= STATUS_FLAG_CD;
|
||||
if ((data[0] & GET_CONTROL_HXN_FLAG_RI) == 0) mStatus |= STATUS_FLAG_RI;
|
||||
} else {
|
||||
byte[] data = vendorIn(GET_CONTROL_REQUEST, 0, 1);
|
||||
if ((data[0] & GET_CONTROL_FLAG_CTS) == 0) mStatus |= STATUS_FLAG_CTS;
|
||||
if ((data[0] & GET_CONTROL_FLAG_DSR) == 0) mStatus |= STATUS_FLAG_DSR;
|
||||
if ((data[0] & GET_CONTROL_FLAG_CD) == 0) mStatus |= STATUS_FLAG_CD;
|
||||
if ((data[0] & GET_CONTROL_FLAG_RI) == 0) mStatus |= STATUS_FLAG_RI;
|
||||
}
|
||||
//Log.d(TAG, "start control line status thread " + mStatus);
|
||||
mReadStatusThread = new Thread(this::readStatusThreadFunction);
|
||||
mReadStatusThread.setDaemon(true);
|
||||
|
@ -266,12 +303,14 @@ public class ProlificSerialDriver implements UsbSerialDriver {
|
|||
mDeviceType = DeviceType.DEVICE_TYPE_T; // TA
|
||||
} else if(deviceVersion == 0x500) {
|
||||
mDeviceType = DeviceType.DEVICE_TYPE_T; // TB
|
||||
} else if(usbVersion == 0x200 && !testHxStatus()) {
|
||||
mDeviceType = DeviceType.DEVICE_TYPE_HXN;
|
||||
} else {
|
||||
mDeviceType = DeviceType.DEVICE_TYPE_HX;
|
||||
}
|
||||
setControlLines(mControlLinesValue);
|
||||
resetDevice();
|
||||
doBlackMagic();
|
||||
setControlLines(mControlLinesValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -304,6 +343,9 @@ public class ProlificSerialDriver implements UsbSerialDriver {
|
|||
if (baudRate <= 0) {
|
||||
throw new IllegalArgumentException("Invalid baud rate: " + baudRate);
|
||||
}
|
||||
if (mDeviceType == DeviceType.DEVICE_TYPE_HXN) {
|
||||
return baudRate;
|
||||
}
|
||||
for(int br : standardBaudRates) {
|
||||
if (br == baudRate) {
|
||||
return baudRate;
|
||||
|
@ -501,12 +543,17 @@ public class ProlificSerialDriver implements UsbSerialDriver {
|
|||
|
||||
@Override
|
||||
public void purgeHwBuffers(boolean purgeWriteBuffers, boolean purgeReadBuffers) throws IOException {
|
||||
if (purgeWriteBuffers) {
|
||||
vendorOut(FLUSH_RX_REQUEST, 0, null);
|
||||
}
|
||||
|
||||
if (purgeReadBuffers) {
|
||||
vendorOut(FLUSH_TX_REQUEST, 0, null);
|
||||
if (mDeviceType == DeviceType.DEVICE_TYPE_HXN) {
|
||||
int index = 0;
|
||||
if(purgeWriteBuffers) index |= RESET_HXN_RX_PIPE;
|
||||
if(purgeReadBuffers) index |= RESET_HXN_TX_PIPE;
|
||||
if(index != 0)
|
||||
vendorOut(RESET_HXN_REQUEST, index, null);
|
||||
} else {
|
||||
if (purgeWriteBuffers)
|
||||
vendorOut(FLUSH_RX_REQUEST, 0, null);
|
||||
if (purgeReadBuffers)
|
||||
vendorOut(FLUSH_TX_REQUEST, 0, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -519,7 +566,15 @@ public class ProlificSerialDriver implements UsbSerialDriver {
|
|||
public static Map<Integer, int[]> getSupportedDevices() {
|
||||
final Map<Integer, int[]> supportedDevices = new LinkedHashMap<>();
|
||||
supportedDevices.put(UsbId.VENDOR_PROLIFIC,
|
||||
new int[] { UsbId.PROLIFIC_PL2303, });
|
||||
new int[] {
|
||||
UsbId.PROLIFIC_PL2303,
|
||||
UsbId.PROLIFIC_PL2303GC,
|
||||
UsbId.PROLIFIC_PL2303GB,
|
||||
UsbId.PROLIFIC_PL2303GT,
|
||||
UsbId.PROLIFIC_PL2303GL,
|
||||
UsbId.PROLIFIC_PL2303GE,
|
||||
UsbId.PROLIFIC_PL2303GS,
|
||||
});
|
||||
return supportedDevices;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,13 @@ public final class UsbId {
|
|||
public static final int SILABS_CP2108 = 0xea71;
|
||||
|
||||
public static final int VENDOR_PROLIFIC = 0x067b;
|
||||
public static final int PROLIFIC_PL2303 = 0x2303;
|
||||
public static final int PROLIFIC_PL2303 = 0x2303; // device type 01, T, HX
|
||||
public static final int PROLIFIC_PL2303GC = 0x23a3; // device type HXN
|
||||
public static final int PROLIFIC_PL2303GB = 0x23b3; // "
|
||||
public static final int PROLIFIC_PL2303GT = 0x23cd; // "
|
||||
public static final int PROLIFIC_PL2303GL = 0x23e3; // "
|
||||
public static final int PROLIFIC_PL2303GE = 0x23e3; // "
|
||||
public static final int PROLIFIC_PL2303GS = 0x23f3; // "
|
||||
|
||||
public static final int VENDOR_QINHENG = 0x1a86;
|
||||
public static final int QINHENG_CH340 = 0x7523;
|
||||
|
|
Ładowanie…
Reference in New Issue