mirror of
				https://github.com/mik3y/usb-serial-for-android
				synced 2025-10-30 18:07:21 +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