mirror of
https://github.com/mik3y/usb-serial-for-android
synced 2025-06-08 00:16:13 +00:00
PL2303(HX) support non-standard baud rates
This commit is contained in:
parent
1adf2a9b98
commit
732e138630
@ -302,8 +302,25 @@ public class DeviceTest {
|
|||||||
28800, 38400, 57600, 115200, 128000, 134400, 161280, 201600, 230400, 268800,
|
28800, 38400, 57600, 115200, 128000, 134400, 161280, 201600, 230400, 268800,
|
||||||
403200, 460800, 614400, 806400, 921600, 1228800, 2457600, 3000000, /*6000000*/
|
403200, 460800, 614400, 806400, 921600, 1228800, 2457600, 3000000, /*6000000*/
|
||||||
};
|
};
|
||||||
for(int baudRate : baudRates) {
|
|
||||||
usb.open();
|
usb.open();
|
||||||
|
|
||||||
|
try {
|
||||||
|
usb.setParameters(45, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||||
|
fail("baud rate to low expected");
|
||||||
|
} catch(UnsupportedOperationException ignored) {}
|
||||||
|
usb.setParameters(46, 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);
|
||||||
|
fail("baud rate to high expected");
|
||||||
|
} catch(UnsupportedOperationException ignored) {}
|
||||||
|
usb.setParameters(11_636_363, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||||
|
try {
|
||||||
|
usb.setParameters(11_636_364, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||||
|
fail("baud rate deviation to high expected");
|
||||||
|
} catch(UnsupportedOperationException ignored) {}
|
||||||
|
|
||||||
|
for(int baudRate : baudRates) {
|
||||||
int readWait = 500;
|
int readWait = 500;
|
||||||
if(baudRate < 300) readWait = 1000;
|
if(baudRate < 300) readWait = 1000;
|
||||||
if(baudRate < 150) readWait = 2000;
|
if(baudRate < 150) readWait = 2000;
|
||||||
@ -311,40 +328,31 @@ public class DeviceTest {
|
|||||||
usb.setParameters(baudRate, 8, 1, UsbSerialPort.PARITY_NONE);
|
usb.setParameters(baudRate, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||||
doReadWrite(String.valueOf(baudRate), readWait);
|
doReadWrite(String.valueOf(baudRate), readWait);
|
||||||
|
|
||||||
try {
|
|
||||||
usb.setParameters(baudRate + 1, 8, 1, UsbSerialPort.PARITY_NONE);
|
usb.setParameters(baudRate + 1, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||||
fail("unsupported baud rate error expected "+baudRate);
|
doReadWrite(String.valueOf(baudRate + 1), readWait);
|
||||||
} catch(UnsupportedOperationException ignored) {}
|
|
||||||
|
|
||||||
usb.setParameters(baudRate + (1<<29), 8, 1, UsbSerialPort.PARITY_NONE);
|
|
||||||
doReadWrite(String.valueOf(baudRate) + " + 1<<29", readWait);
|
|
||||||
|
|
||||||
// silent fallback to 9600 for unsupported baud rates
|
// silent fallback to 9600 for unsupported baud rates
|
||||||
telnet.setParameters(9600, 8, 1, UsbSerialPort.PARITY_NONE);
|
telnet.setParameters(9600, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||||
usb.setParameters(baudRate + 1 + (1<<29), 8, 1, UsbSerialPort.PARITY_NONE);
|
usb.setParameters(baudRate + 1 + (1<<29), 8, 1, UsbSerialPort.PARITY_NONE);
|
||||||
doReadWrite(String.valueOf(baudRate + 1) + " + 1<<29", readWait);
|
doReadWrite(String.valueOf(baudRate + 1) + " + 1<<29", readWait);
|
||||||
usb.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// some PL2303... data sheets mention additional baud rates, others don't
|
// some PL2303... data sheets mention additional baud rates, others don't
|
||||||
// they do not work with my devices and linux driver also excludes them
|
// they do not work with my devices and linux driver also excludes them
|
||||||
usb.open();
|
|
||||||
telnet.setParameters(9600, 8, 1, UsbSerialPort.PARITY_NONE);
|
|
||||||
baudRates = new int[]{110, 56000, 256000};
|
baudRates = new int[]{110, 56000, 256000};
|
||||||
for(int baudRate : baudRates) {
|
for(int baudRate : baudRates) {
|
||||||
int readWait = 500;
|
int readWait = 500;
|
||||||
if(baudRate < 300) readWait = 1000;
|
if(baudRate < 300) readWait = 1000;
|
||||||
if(baudRate < 150) readWait = 2000;
|
if(baudRate < 150) readWait = 2000;
|
||||||
try {
|
telnet.setParameters(baudRate, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||||
usb.setParameters(baudRate, 8, 1, UsbSerialPort.PARITY_NONE);
|
usb.setParameters(baudRate, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||||
fail("unsupported baud rate error expected "+baudRate);
|
doReadWrite(String.valueOf(baudRate), readWait);
|
||||||
} catch(UnsupportedOperationException ignored) {}
|
|
||||||
|
|
||||||
// silent fallback to 9600 for unsupported baud rates
|
// silent fallback to 9600 for unsupported baud rates
|
||||||
|
telnet.setParameters(9600, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||||
usb.setParameters(baudRate + (1<<29), 8, 1, UsbSerialPort.PARITY_NONE);
|
usb.setParameters(baudRate + (1<<29), 8, 1, UsbSerialPort.PARITY_NONE);
|
||||||
doReadWrite(String.valueOf(baudRate ) + " + 1<<29", readWait);
|
doReadWrite(String.valueOf(baudRate ) + " + 1<<29", readWait);
|
||||||
}
|
}
|
||||||
usb.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -460,12 +468,6 @@ public class DeviceTest {
|
|||||||
doReadWrite(baudRate+"/8N1");
|
doReadWrite(baudRate+"/8N1");
|
||||||
}
|
}
|
||||||
if(rfc2217_server_nonstandard_baudrates && !isCp21xxRestrictedPort) {
|
if(rfc2217_server_nonstandard_baudrates && !isCp21xxRestrictedPort) {
|
||||||
if (usb.serialDriver instanceof ProlificSerialDriver) {
|
|
||||||
try {
|
|
||||||
usb.setParameters(42000, 8, 1, UsbSerialPort.PARITY_NONE);
|
|
||||||
fail("unsupported baud rate error expected");
|
|
||||||
} catch (UnsupportedOperationException ignored) {}
|
|
||||||
} else {
|
|
||||||
usb.setParameters(42000, 8, 1, UsbSerialPort.PARITY_NONE);
|
usb.setParameters(42000, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||||
telnet.setParameters(42000, 8, 1, UsbSerialPort.PARITY_NONE);
|
telnet.setParameters(42000, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||||
|
|
||||||
@ -491,7 +493,6 @@ public class DeviceTest {
|
|||||||
assertThat("42000/8N1", data2, equalTo(buf2));
|
assertThat("42000/8N1", data2, equalTo(buf2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
{ // non matching baud rate
|
{ // non matching baud rate
|
||||||
telnet.setParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE);
|
telnet.setParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||||
usb.setParameters(2400, 8, 1, UsbSerialPort.PARITY_NONE);
|
usb.setParameters(2400, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||||
|
@ -176,7 +176,7 @@ public class FtdiSerialDriver implements UsbSerialDriver {
|
|||||||
private void setBaudrate(int baudRate) throws IOException {
|
private void setBaudrate(int baudRate) throws IOException {
|
||||||
int divisor, subdivisor, effectiveBaudRate;
|
int divisor, subdivisor, effectiveBaudRate;
|
||||||
if (baudRate > 3500000) {
|
if (baudRate > 3500000) {
|
||||||
throw new IOException("Baud rate to high");
|
throw new UnsupportedOperationException("Baud rate to high");
|
||||||
} else if(baudRate >= 2500000) {
|
} else if(baudRate >= 2500000) {
|
||||||
divisor = 0;
|
divisor = 0;
|
||||||
subdivisor = 0;
|
subdivisor = 0;
|
||||||
@ -191,13 +191,13 @@ public class FtdiSerialDriver implements UsbSerialDriver {
|
|||||||
subdivisor = divisor & 0x07;
|
subdivisor = divisor & 0x07;
|
||||||
divisor >>= 3;
|
divisor >>= 3;
|
||||||
if (divisor > 0x3fff) // exceeds bit 13 at 183 baud
|
if (divisor > 0x3fff) // exceeds bit 13 at 183 baud
|
||||||
throw new IOException("Baud rate to low");
|
throw new UnsupportedOperationException("Baud rate to low");
|
||||||
effectiveBaudRate = (24000000 << 1) / ((divisor << 3) + subdivisor);
|
effectiveBaudRate = (24000000 << 1) / ((divisor << 3) + subdivisor);
|
||||||
effectiveBaudRate = (effectiveBaudRate +1) >> 1;
|
effectiveBaudRate = (effectiveBaudRate +1) >> 1;
|
||||||
}
|
}
|
||||||
double baudRateError = Math.abs(1.0 - (effectiveBaudRate / (double)baudRate));
|
double baudRateError = Math.abs(1.0 - (effectiveBaudRate / (double)baudRate));
|
||||||
if(baudRateError >= 0.031) // can happen only > 1.5Mbaud
|
if(baudRateError >= 0.031) // can happen only > 1.5Mbaud
|
||||||
throw new IOException(String.format("baud rate deviation %.1f%% is higher than allowed 3%%", baudRateError*100));
|
throw new UnsupportedOperationException(String.format("Baud rate deviation %.1f%% is higher than allowed 3%%", baudRateError*100));
|
||||||
int value = divisor;
|
int value = divisor;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
switch(subdivisor) {
|
switch(subdivisor) {
|
||||||
|
@ -19,6 +19,7 @@ import android.util.Log;
|
|||||||
import com.hoho.android.usbserial.BuildConfig;
|
import com.hoho.android.usbserial.BuildConfig;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@ -34,7 +35,7 @@ public class ProlificSerialDriver implements UsbSerialDriver {
|
|||||||
28800, 38400, 57600, 115200, 128000, 134400, 161280, 201600, 230400, 268800,
|
28800, 38400, 57600, 115200, 128000, 134400, 161280, 201600, 230400, 268800,
|
||||||
403200, 460800, 614400, 806400, 921600, 1228800, 2457600, 3000000, 6000000
|
403200, 460800, 614400, 806400, 921600, 1228800, 2457600, 3000000, 6000000
|
||||||
};
|
};
|
||||||
|
private enum DeviceType { DEVICE_TYPE_01, DEVICE_TYPE_HX};
|
||||||
|
|
||||||
private final UsbDevice mDevice;
|
private final UsbDevice mDevice;
|
||||||
private final UsbSerialPort mPort;
|
private final UsbSerialPort mPort;
|
||||||
@ -89,11 +90,7 @@ public class ProlificSerialDriver implements UsbSerialDriver {
|
|||||||
private static final int STATUS_BUFFER_SIZE = 10;
|
private static final int STATUS_BUFFER_SIZE = 10;
|
||||||
private static final int STATUS_BYTE_IDX = 8;
|
private static final int STATUS_BYTE_IDX = 8;
|
||||||
|
|
||||||
private static final int DEVICE_TYPE_HX = 0;
|
private DeviceType mDeviceType = DeviceType.DEVICE_TYPE_HX;
|
||||||
private static final int DEVICE_TYPE_0 = 1;
|
|
||||||
private static final int DEVICE_TYPE_1 = 2;
|
|
||||||
|
|
||||||
private int mDeviceType = DEVICE_TYPE_HX;
|
|
||||||
private UsbEndpoint mInterruptEndpoint;
|
private UsbEndpoint mInterruptEndpoint;
|
||||||
private int mControlLinesValue = 0;
|
private int mControlLinesValue = 0;
|
||||||
private int mBaudRate = -1, mDataBits = -1, mStopBits = -1, mParity = -1;
|
private int mBaudRate = -1, mDataBits = -1, mStopBits = -1, mParity = -1;
|
||||||
@ -172,7 +169,7 @@ public class ProlificSerialDriver implements UsbSerialDriver {
|
|||||||
vendorIn(0x8383, 0, 1);
|
vendorIn(0x8383, 0, 1);
|
||||||
vendorOut(0, 1, null);
|
vendorOut(0, 1, null);
|
||||||
vendorOut(1, 0, null);
|
vendorOut(1, 0, null);
|
||||||
vendorOut(2, (mDeviceType == DEVICE_TYPE_HX) ? 0x44 : 0x24, null);
|
vendorOut(2, (mDeviceType == DeviceType.DEVICE_TYPE_HX) ? 0x44 : 0x24, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setControlLines(int newControlLinesValue) throws IOException {
|
private void setControlLines(int newControlLinesValue) throws IOException {
|
||||||
@ -272,22 +269,22 @@ public class ProlificSerialDriver implements UsbSerialDriver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mDevice.getDeviceClass() == 0x02) {
|
if (mDevice.getDeviceClass() == 0x02) {
|
||||||
mDeviceType = DEVICE_TYPE_0;
|
mDeviceType = DeviceType.DEVICE_TYPE_01;
|
||||||
} else {
|
} else {
|
||||||
byte[] rawDescriptors = connection.getRawDescriptors();
|
byte[] rawDescriptors = connection.getRawDescriptors();
|
||||||
if(rawDescriptors == null || rawDescriptors.length <8) {
|
if(rawDescriptors == null || rawDescriptors.length <8) {
|
||||||
Log.w(TAG, "Could not get device descriptors, Assuming that it is a HX device");
|
Log.w(TAG, "Could not get device descriptors, Assuming that it is a HX device");
|
||||||
mDeviceType = DEVICE_TYPE_HX;
|
mDeviceType = DeviceType.DEVICE_TYPE_HX;
|
||||||
} else {
|
} else {
|
||||||
byte maxPacketSize0 = rawDescriptors[7];
|
byte maxPacketSize0 = rawDescriptors[7];
|
||||||
if (maxPacketSize0 == 64) {
|
if (maxPacketSize0 == 64) {
|
||||||
mDeviceType = DEVICE_TYPE_HX;
|
mDeviceType = DeviceType.DEVICE_TYPE_HX;
|
||||||
} else if ((mDevice.getDeviceClass() == 0x00)
|
} else if ((mDevice.getDeviceClass() == 0x00)
|
||||||
|| (mDevice.getDeviceClass() == 0xff)) {
|
|| (mDevice.getDeviceClass() == 0xff)) {
|
||||||
mDeviceType = DEVICE_TYPE_1;
|
mDeviceType = DeviceType.DEVICE_TYPE_01;
|
||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "Could not detect PL2303 subtype, Assuming that it is a HX device");
|
Log.w(TAG, "Could not detect PL2303 subtype, Assuming that it is a HX device");
|
||||||
mDeviceType = DEVICE_TYPE_HX;
|
mDeviceType = DeviceType.DEVICE_TYPE_HX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -328,7 +325,40 @@ public class ProlificSerialDriver implements UsbSerialDriver {
|
|||||||
return baudRate;
|
return baudRate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new UnsupportedOperationException("Unsupported baud rate: " + baudRate);
|
/*
|
||||||
|
* Formula taken from Linux + FreeBSD.
|
||||||
|
* 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;
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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));
|
||||||
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user