diff --git a/usbSerialForAndroid/src/androidTest/java/com/hoho/android/usbserial/DeviceTest.java b/usbSerialForAndroid/src/androidTest/java/com/hoho/android/usbserial/DeviceTest.java index c02c7f2..f6a86a5 100644 --- a/usbSerialForAndroid/src/androidTest/java/com/hoho/android/usbserial/DeviceTest.java +++ b/usbSerialForAndroid/src/androidTest/java/com/hoho/android/usbserial/DeviceTest.java @@ -26,6 +26,7 @@ import com.hoho.android.usbserial.driver.Cp21xxSerialDriver; import com.hoho.android.usbserial.driver.FtdiSerialDriver; import com.hoho.android.usbserial.driver.ProbeTable; import com.hoho.android.usbserial.driver.ProlificSerialDriver; +import com.hoho.android.usbserial.driver.ProlificWrapper; import com.hoho.android.usbserial.driver.SerialTimeoutException; import com.hoho.android.usbserial.driver.UsbId; import com.hoho.android.usbserial.driver.UsbSerialDriver; @@ -323,11 +324,12 @@ public class DeviceTest { }; usb.open(); + int minBaudRate = ProlificWrapper.isDeviceTypeT(usb.serialPort) ? 6 : 46; try { - usb.setParameters(45, 8, 1, UsbSerialPort.PARITY_NONE); + usb.setParameters(minBaudRate-1, 8, 1, UsbSerialPort.PARITY_NONE); fail("baud rate to low expected"); } catch(UnsupportedOperationException ignored) {} - usb.setParameters(46, 8, 1, UsbSerialPort.PARITY_NONE); + usb.setParameters(minBaudRate, 8, 1, UsbSerialPort.PARITY_NONE); usb.setParameters(384_000_000, 8, 1, UsbSerialPort.PARITY_NONE); try { usb.setParameters(384_000_001, 8, 1, UsbSerialPort.PARITY_NONE); diff --git a/usbSerialForAndroid/src/androidTest/java/com/hoho/android/usbserial/driver/ProlificWrapper.java b/usbSerialForAndroid/src/androidTest/java/com/hoho/android/usbserial/driver/ProlificWrapper.java new file mode 100644 index 0000000..c9e37d0 --- /dev/null +++ b/usbSerialForAndroid/src/androidTest/java/com/hoho/android/usbserial/driver/ProlificWrapper.java @@ -0,0 +1,8 @@ +package com.hoho.android.usbserial.driver; + +public class ProlificWrapper { + public static boolean isDeviceTypeT(UsbSerialPort serialPort) { + ProlificSerialDriver.ProlificSerialPort prolificSerialPort = (ProlificSerialDriver.ProlificSerialPort) serialPort; + return prolificSerialPort.mDeviceType == ProlificSerialDriver.DeviceType.DEVICE_TYPE_T; + } +} diff --git a/usbSerialForAndroid/src/androidTest/java/com/hoho/android/usbserial/util/UsbWrapper.java b/usbSerialForAndroid/src/androidTest/java/com/hoho/android/usbserial/util/UsbWrapper.java index c62f655..932bdb1 100644 --- a/usbSerialForAndroid/src/androidTest/java/com/hoho/android/usbserial/util/UsbWrapper.java +++ b/usbSerialForAndroid/src/androidTest/java/com/hoho/android/usbserial/util/UsbWrapper.java @@ -21,7 +21,6 @@ import java.util.Deque; import java.util.EnumSet; import java.util.LinkedList; import java.util.concurrent.Callable; -import java.util.concurrent.Executors; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; diff --git a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/ProlificSerialDriver.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/ProlificSerialDriver.java index a61b01a..bfc878b 100644 --- a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/ProlificSerialDriver.java +++ b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/ProlificSerialDriver.java @@ -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 }; - private enum DeviceType { DEVICE_TYPE_01, DEVICE_TYPE_HX} + protected enum DeviceType { DEVICE_TYPE_01, DEVICE_TYPE_T, DEVICE_TYPE_HX} private final UsbDevice mDevice; private final UsbSerialPort mPort; @@ -98,7 +98,7 @@ public class ProlificSerialDriver implements UsbSerialDriver { private static final int STATUS_BUFFER_SIZE = 10; private static final int STATUS_BYTE_IDX = 8; - private DeviceType mDeviceType = DeviceType.DEVICE_TYPE_HX; + protected DeviceType mDeviceType = DeviceType.DEVICE_TYPE_HX; private UsbEndpoint mInterruptEndpoint; private int mControlLinesValue = 0; private int mBaudRate = -1, mDataBits = -1, mStopBits = -1, mParity = -1; @@ -163,7 +163,7 @@ public class ProlificSerialDriver implements UsbSerialDriver { vendorIn(0x8383, 0, 1); vendorOut(0, 1, null); vendorOut(1, 0, null); - vendorOut(2, (mDeviceType == DeviceType.DEVICE_TYPE_HX) ? 0x44 : 0x24, null); + vendorOut(2, (mDeviceType == DeviceType.DEVICE_TYPE_01) ? 0x24 : 0x44, null); } private void setControlLines(int newControlLinesValue) throws IOException { @@ -253,25 +253,21 @@ public class ProlificSerialDriver implements UsbSerialDriver { } } - if (mDevice.getDeviceClass() == 0x02) { + byte[] rawDescriptors = connection.getRawDescriptors(); + if(rawDescriptors == null || rawDescriptors.length < 14) { + throw new IOException("Could not get device descriptors"); + } + int usbVersion = (rawDescriptors[3] << 8) + rawDescriptors[2]; + int deviceVersion = (rawDescriptors[13] << 8) + rawDescriptors[12]; + byte maxPacketSize0 = rawDescriptors[7]; + if (mDevice.getDeviceClass() == 0x02 || maxPacketSize0 != 64) { mDeviceType = DeviceType.DEVICE_TYPE_01; + } else if(deviceVersion == 0x300 && usbVersion == 0x200) { + mDeviceType = DeviceType.DEVICE_TYPE_T; // TA + } else if(deviceVersion == 0x500) { + mDeviceType = DeviceType.DEVICE_TYPE_T; // TB } else { - byte[] rawDescriptors = connection.getRawDescriptors(); - if(rawDescriptors == null || rawDescriptors.length <8) { - Log.w(TAG, "Could not get device descriptors, Assuming that it is a HX device"); - mDeviceType = DeviceType.DEVICE_TYPE_HX; - } else { - byte maxPacketSize0 = rawDescriptors[7]; - if (maxPacketSize0 == 64) { - mDeviceType = DeviceType.DEVICE_TYPE_HX; - } else if ((mDevice.getDeviceClass() == 0x00) - || (mDevice.getDeviceClass() == 0xff)) { - mDeviceType = DeviceType.DEVICE_TYPE_01; - } else { - Log.w(TAG, "Could not detect PL2303 subtype, Assuming that it is a HX device"); - mDeviceType = DeviceType.DEVICE_TYPE_HX; - } - } + mDeviceType = DeviceType.DEVICE_TYPE_HX; } setControlLines(mControlLinesValue); resetDevice(); @@ -315,34 +311,53 @@ public class ProlificSerialDriver implements UsbSerialDriver { } /* * Formula taken from Linux + FreeBSD. + * + * For TA+TB devices + * baudrate = baseline / (mantissa * 2^exponent) + * where + * mantissa = buf[10:0] + * exponent = buf[15:13 16] + * + * For other devices * baudrate = baseline / (mantissa * 4^exponent) * where * mantissa = buf[8:0] * exponent = buf[11:9] * - * Note: The formula does not work for all PL2303 variants. - * Ok for PL2303HX. Not ok for PL2303TA. Other variants unknown. */ - int baseline, mantissa, exponent; + int baseline, mantissa, exponent, buf, effectiveBaudRate; baseline = 12000000 * 32; mantissa = baseline / baudRate; if (mantissa == 0) { // > unrealistic 384 MBaud throw new UnsupportedOperationException("Baud rate to high"); } exponent = 0; - while (mantissa >= 512) { - if (exponent < 7) { - mantissa >>= 2; /* divide by 4 */ - exponent++; - } else { // < 45.8 baud - throw new UnsupportedOperationException("Baud rate to low"); + if (mDeviceType == DeviceType.DEVICE_TYPE_T) { + while (mantissa >= 2048) { + if (exponent < 15) { + mantissa >>= 1; /* divide by 2 */ + exponent++; + } else { // < 7 baud + throw new UnsupportedOperationException("Baud rate to low"); + } } + buf = mantissa + ((exponent & ~1) << 12) + ((exponent & 1) << 16) + (1 << 31); + effectiveBaudRate = (baseline / mantissa) >> exponent; + } else { + while (mantissa >= 512) { + if (exponent < 7) { + mantissa >>= 2; /* divide by 4 */ + exponent++; + } else { // < 45.8 baud + throw new UnsupportedOperationException("Baud rate to low"); + } + } + buf = mantissa + (exponent << 9) + (1 << 31); + effectiveBaudRate = (baseline / mantissa) >> (exponent << 1); } - int effectiveBaudRate = (baseline / mantissa) >> (exponent << 1); double baudRateError = Math.abs(1.0 - (effectiveBaudRate / (double)baudRate)); if(baudRateError >= 0.031) // > unrealistic 11.6 Mbaud throw new UnsupportedOperationException(String.format("Baud rate deviation %.1f%% is higher than allowed 3%%", baudRateError*100)); - int buf = mantissa + (exponent<<9) + (1<<31); Log.d(TAG, String.format("baud rate=%d, effective=%d, error=%.1f%%, value=0x%08x, mantissa=%d, exponent=%d", baudRate, effectiveBaudRate, baudRateError*100, buf, mantissa, exponent));