mirror of
				https://github.com/mik3y/usb-serial-for-android
				synced 2025-10-31 02:17:23 +00:00 
			
		
		
		
	custom baud rates for PL2303TA/TB
see https://lore.kernel.org/r/3aee5708-7961-f464-8c5f-6685d96920d6@IEEE.org
This commit is contained in:
		
							parent
							
								
									22a685e738
								
							
						
					
					
						commit
						2f23bdfb6d
					
				| @ -26,6 +26,7 @@ import com.hoho.android.usbserial.driver.Cp21xxSerialDriver; | |||||||
| import com.hoho.android.usbserial.driver.FtdiSerialDriver; | import com.hoho.android.usbserial.driver.FtdiSerialDriver; | ||||||
| import com.hoho.android.usbserial.driver.ProbeTable; | import com.hoho.android.usbserial.driver.ProbeTable; | ||||||
| import com.hoho.android.usbserial.driver.ProlificSerialDriver; | 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.SerialTimeoutException; | ||||||
| import com.hoho.android.usbserial.driver.UsbId; | import com.hoho.android.usbserial.driver.UsbId; | ||||||
| import com.hoho.android.usbserial.driver.UsbSerialDriver; | import com.hoho.android.usbserial.driver.UsbSerialDriver; | ||||||
| @ -323,11 +324,12 @@ public class DeviceTest { | |||||||
|         }; |         }; | ||||||
|         usb.open(); |         usb.open(); | ||||||
| 
 | 
 | ||||||
|  |         int minBaudRate = ProlificWrapper.isDeviceTypeT(usb.serialPort) ? 6 : 46; | ||||||
|         try { |         try { | ||||||
|             usb.setParameters(45, 8, 1, UsbSerialPort.PARITY_NONE); |             usb.setParameters(minBaudRate-1, 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|             fail("baud rate to low expected"); |             fail("baud rate to low expected"); | ||||||
|         } catch(UnsupportedOperationException ignored) {} |         } 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); |         usb.setParameters(384_000_000, 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|         try { |         try { | ||||||
|             usb.setParameters(384_000_001, 8, 1, UsbSerialPort.PARITY_NONE); |             usb.setParameters(384_000_001, 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|  | |||||||
| @ -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; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -21,7 +21,6 @@ import java.util.Deque; | |||||||
| import java.util.EnumSet; | import java.util.EnumSet; | ||||||
| import java.util.LinkedList; | import java.util.LinkedList; | ||||||
| import java.util.concurrent.Callable; | import java.util.concurrent.Callable; | ||||||
| import java.util.concurrent.Executors; |  | ||||||
| 
 | 
 | ||||||
| import static org.junit.Assert.assertEquals; | import static org.junit.Assert.assertEquals; | ||||||
| import static org.junit.Assert.assertTrue; | import static org.junit.Assert.assertTrue; | ||||||
|  | |||||||
| @ -35,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} |     protected enum DeviceType { DEVICE_TYPE_01, DEVICE_TYPE_T, DEVICE_TYPE_HX} | ||||||
| 
 | 
 | ||||||
|     private final UsbDevice mDevice; |     private final UsbDevice mDevice; | ||||||
|     private final UsbSerialPort mPort; |     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_BUFFER_SIZE = 10; | ||||||
|         private static final int STATUS_BYTE_IDX = 8; |         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 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; | ||||||
| @ -163,7 +163,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 == DeviceType.DEVICE_TYPE_HX) ? 0x44 : 0x24, null); |             vendorOut(2, (mDeviceType == DeviceType.DEVICE_TYPE_01) ? 0x24 : 0x44, null); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         private void setControlLines(int newControlLinesValue) throws IOException { |         private void setControlLines(int newControlLinesValue) throws IOException { | ||||||
| @ -253,26 +253,22 @@ public class ProlificSerialDriver implements UsbSerialDriver { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (mDevice.getDeviceClass() == 0x02) { |  | ||||||
|                 mDeviceType = DeviceType.DEVICE_TYPE_01; |  | ||||||
|             } else { |  | ||||||
|             byte[] rawDescriptors = connection.getRawDescriptors(); |             byte[] rawDescriptors = connection.getRawDescriptors(); | ||||||
|                 if(rawDescriptors == null || rawDescriptors.length <8) { |             if(rawDescriptors == null || rawDescriptors.length < 14) { | ||||||
|                     Log.w(TAG, "Could not get device descriptors, Assuming that it is a HX device"); |                 throw new IOException("Could not get device descriptors"); | ||||||
|                     mDeviceType = DeviceType.DEVICE_TYPE_HX; |             } | ||||||
|                 } else { |             int usbVersion = (rawDescriptors[3] << 8) + rawDescriptors[2]; | ||||||
|  |             int deviceVersion = (rawDescriptors[13] << 8) + rawDescriptors[12]; | ||||||
|             byte maxPacketSize0 = rawDescriptors[7]; |             byte maxPacketSize0 = rawDescriptors[7]; | ||||||
|                     if (maxPacketSize0 == 64) { |             if (mDevice.getDeviceClass() == 0x02 || maxPacketSize0 != 64) { | ||||||
|                         mDeviceType = DeviceType.DEVICE_TYPE_HX; |  | ||||||
|                     } else if ((mDevice.getDeviceClass() == 0x00) |  | ||||||
|                             || (mDevice.getDeviceClass() == 0xff)) { |  | ||||||
|                 mDeviceType = DeviceType.DEVICE_TYPE_01; |                 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 { |             } 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); |             setControlLines(mControlLinesValue); | ||||||
|             resetDevice(); |             resetDevice(); | ||||||
|             doBlackMagic(); |             doBlackMagic(); | ||||||
| @ -315,21 +311,39 @@ public class ProlificSerialDriver implements UsbSerialDriver { | |||||||
|             } |             } | ||||||
|             /* |             /* | ||||||
|              * Formula taken from Linux + FreeBSD. |              * 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) |              *   baudrate = baseline / (mantissa * 4^exponent) | ||||||
|              * where |              * where | ||||||
|              *   mantissa = buf[8:0] |              *   mantissa = buf[8:0] | ||||||
|              *   exponent = buf[11:9] |              *   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; |             baseline = 12000000 * 32; | ||||||
|             mantissa = baseline / baudRate; |             mantissa = baseline / baudRate; | ||||||
|             if (mantissa == 0) { // > unrealistic 384 MBaud |             if (mantissa == 0) { // > unrealistic 384 MBaud | ||||||
|                 throw new UnsupportedOperationException("Baud rate to high"); |                 throw new UnsupportedOperationException("Baud rate to high"); | ||||||
|             } |             } | ||||||
|             exponent = 0; |             exponent = 0; | ||||||
|  |             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) { |                 while (mantissa >= 512) { | ||||||
|                     if (exponent < 7) { |                     if (exponent < 7) { | ||||||
|                         mantissa >>= 2;    /* divide by 4 */ |                         mantissa >>= 2;    /* divide by 4 */ | ||||||
| @ -338,11 +352,12 @@ public class ProlificSerialDriver implements UsbSerialDriver { | |||||||
|                         throw new UnsupportedOperationException("Baud rate to low"); |                         throw new UnsupportedOperationException("Baud rate to low"); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             int effectiveBaudRate = (baseline / mantissa) >> (exponent << 1); |                 buf = mantissa + (exponent << 9) + (1 << 31); | ||||||
|  |                 effectiveBaudRate = (baseline / mantissa) >> (exponent << 1); | ||||||
|  |             } | ||||||
|             double baudRateError = Math.abs(1.0 - (effectiveBaudRate / (double)baudRate)); |             double baudRateError = Math.abs(1.0 - (effectiveBaudRate / (double)baudRate)); | ||||||
|             if(baudRateError >= 0.031) // > unrealistic 11.6 Mbaud |             if(baudRateError >= 0.031) // > unrealistic 11.6 Mbaud | ||||||
|                 throw new UnsupportedOperationException(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 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", |             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)); |                     baudRate, effectiveBaudRate, baudRateError*100, buf, mantissa, exponent)); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user