mirror of
				https://github.com/mik3y/usb-serial-for-android
				synced 2025-10-31 02:17:23 +00:00 
			
		
		
		
	rewrite ftdi driver without LGPL code from libftdi
This commit is contained in:
		
							parent
							
								
									e0ed25b85f
								
							
						
					
					
						commit
						e496195bd9
					
				| @ -158,9 +158,6 @@ complete license. | |||||||
| 
 | 
 | ||||||
| Copyright 2011-2012, Google Inc. All Rights Reserved. | Copyright 2011-2012, Google Inc. All Rights Reserved. | ||||||
| 
 | 
 | ||||||
| Portions of this library are based on [libftdi](http://www.intra2net.com/en/developer/libftdi). |  | ||||||
| Please see FtdiSerialDriver.java for more information. |  | ||||||
| 
 |  | ||||||
| ## Help & Discussion | ## Help & Discussion | ||||||
| 
 | 
 | ||||||
| For common problems, see the | For common problems, see the | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ publishing { | |||||||
|         maven(MavenPublication) { |         maven(MavenPublication) { | ||||||
|             groupId 'com.github.mik3y' |             groupId 'com.github.mik3y' | ||||||
|             artifactId 'usb-serial-for-android' |             artifactId 'usb-serial-for-android' | ||||||
|             version '2.2.2a' |             version '3.0.0beta' | ||||||
|             afterEvaluate { |             afterEvaluate { | ||||||
|                 artifact androidSourcesJar |                 artifact androidSourcesJar | ||||||
|                 artifact bundleReleaseAar |                 artifact bundleReleaseAar | ||||||
|  | |||||||
| @ -383,6 +383,44 @@ public class DeviceTest { | |||||||
|                 assertThat("42000/8N1", data2, equalTo(buf2)); |                 assertThat("42000/8N1", data2, equalTo(buf2)); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |         if (usbSerialDriver instanceof FtdiSerialDriver) { | ||||||
|  |             try { | ||||||
|  |                 usbParameters(183, 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|  |                 fail("baud rate to low expected"); | ||||||
|  |             } catch (IOException ignored) { | ||||||
|  |             } | ||||||
|  |             usbParameters(184, 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|  |             usbParameters( 960000, 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|  |             usbParameters(1000000, 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|  |             usbParameters(1043478, 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|  |             usbParameters(1090909, 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|  |             usbParameters(1142857, 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|  |             usbParameters(1200000, 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|  |             usbParameters(1263157, 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|  |             usbParameters(1333333, 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|  |             usbParameters(1411764, 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|  |             usbParameters(1500000, 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|  |             try { | ||||||
|  |                 usbParameters((int)(2000000/1.04), 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|  |                 fail("baud rate error expected"); | ||||||
|  |             } catch (IOException ignored) { | ||||||
|  |             } | ||||||
|  |             usbParameters((int)(2000000/1.03), 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|  |             usbParameters(2000000, 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|  |             usbParameters((int)(2000000*1.03), 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|  |             try { | ||||||
|  |                 usbParameters((int)(2000000*1.04), 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|  |                 fail("baud rate error expected"); | ||||||
|  |             } catch (IOException ignored) { | ||||||
|  |             } | ||||||
|  |             usbParameters(2000000, 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|  |             usbParameters(3000000, 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|  |             try { | ||||||
|  |                 usbParameters(4000000, 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|  |                 fail("baud rate to high expected"); | ||||||
|  |             } catch (IOException ignored) { | ||||||
|  |             } | ||||||
|  |         } | ||||||
|         { // 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); | ||||||
| @ -1366,8 +1404,6 @@ public class DeviceTest { | |||||||
|         // control lines retained over close+open |         // control lines retained over close+open | ||||||
|         boolean inputRetained = inputLinesConnected; |         boolean inputRetained = inputLinesConnected; | ||||||
|         boolean outputRetained = true; |         boolean outputRetained = true; | ||||||
|         if(usb.serialDriver instanceof FtdiSerialDriver) |  | ||||||
|             outputRetained = false; // todo |  | ||||||
|         usb.close(EnumSet.of(UsbWrapper.OpenCloseFlags.NO_CONTROL_LINE_INIT)); |         usb.close(EnumSet.of(UsbWrapper.OpenCloseFlags.NO_CONTROL_LINE_INIT)); | ||||||
|         usb.open(EnumSet.of(UsbWrapper.OpenCloseFlags.NO_CONTROL_LINE_INIT, UsbWrapper.OpenCloseFlags.NO_IOMANAGER_THREAD)); |         usb.open(EnumSet.of(UsbWrapper.OpenCloseFlags.NO_CONTROL_LINE_INIT, UsbWrapper.OpenCloseFlags.NO_IOMANAGER_THREAD)); | ||||||
|         usb.setParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE); |         usb.setParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| /* Copyright 2011-2013 Google Inc. | /* Copyright 2011-2013 Google Inc. | ||||||
|  * Copyright 2013 mike wakerly <opensource@hoho.com> |  * Copyright 2013 mike wakerly <opensource@hoho.com> | ||||||
|  |  * Copyright 2020 kai morich <mail@kai-morich.de> | ||||||
|  * |  * | ||||||
|  * This library is free software; you can redistribute it and/or |  * This library is free software; you can redistribute it and/or | ||||||
|  * modify it under the terms of the GNU Lesser General Public |  * modify it under the terms of the GNU Lesser General Public | ||||||
| @ -33,73 +34,22 @@ import java.util.LinkedHashMap; | |||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| 
 | 
 | ||||||
| /** | /* | ||||||
|  * A {@link CommonUsbSerialPort} implementation for a variety of FTDI devices |  * driver is implemented from various information scattered over FTDI documentation | ||||||
|  * <p> |  | ||||||
|  * This driver is based on <a |  | ||||||
|  * href="http://www.intra2net.com/en/developer/libftdi">libftdi</a>, and is |  | ||||||
|  * copyright and subject to the following terms: |  | ||||||
|  * |  * | ||||||
|  * <pre> |  * baud rate calculation https://www.ftdichip.com/Support/Documents/AppNotes/AN232B-05_BaudRates.pdf | ||||||
|  *   Copyright (C) 2003 by Intra2net AG |  * control bits https://www.ftdichip.com/Firmware/Precompiled/UM_VinculumFirmware_V205.pdf | ||||||
|  |  * device type https://www.ftdichip.com/Support/Documents/AppNotes/AN_233_Java_D2XX_for_Android_API_User_Manual.pdf -> bvdDevice | ||||||
|  * |  * | ||||||
|  *   This program is free software; you can redistribute it and/or modify |  | ||||||
|  *   it under the terms of the GNU Lesser General Public License |  | ||||||
|  *   version 2.1 as published by the Free Software Foundation; |  | ||||||
|  * |  | ||||||
|  *   opensource@intra2net.com |  | ||||||
|  *   http://www.intra2net.com/en/developer/libftdi |  | ||||||
|  * </pre> |  | ||||||
|  * |  | ||||||
|  * </p> |  | ||||||
|  * <p> |  | ||||||
|  * Some FTDI devices have not been tested; see later listing of supported and |  | ||||||
|  * unsupported devices. Devices listed as "supported" support the following |  | ||||||
|  * features: |  | ||||||
|  * <ul> |  | ||||||
|  * <li>Read and write of serial data (see |  | ||||||
|  * {@link CommonUsbSerialPort#read(byte[], int)} and |  | ||||||
|  * {@link CommonUsbSerialPort#write(byte[], int)}.</li> |  | ||||||
|  * <li>Setting serial line parameters (see |  | ||||||
|  * {@link CommonUsbSerialPort#setParameters(int, int, int, int)}.</li> |  | ||||||
|  * </ul> |  | ||||||
|  * </p> |  | ||||||
|  * <p> |  | ||||||
|  * Supported and tested devices: |  | ||||||
|  * <ul> |  | ||||||
|  * <li>{@value DeviceType#TYPE_R}</li> |  | ||||||
|  * <li>{@value DeviceType#TYPE_2232H}</li> |  | ||||||
|  * <li>{@value DeviceType#TYPE_4232H}</li> |  | ||||||
|  * </ul> |  | ||||||
|  * </p> |  | ||||||
|  * <p> |  | ||||||
|  * Unsupported but possibly working devices (please contact the author with |  | ||||||
|  * feedback or patches): |  | ||||||
|  * <ul> |  | ||||||
|  * <li>{@value DeviceType#TYPE_2232C}</li> |  | ||||||
|  * <li>{@value DeviceType#TYPE_AM}</li> |  | ||||||
|  * <li>{@value DeviceType#TYPE_BM}</li> |  | ||||||
|  * </ul> |  | ||||||
|  * </p> |  | ||||||
|  * |  | ||||||
|  * @author mike wakerly (opensource@hoho.com) |  | ||||||
|  * @see <a href="https://github.com/mik3y/usb-serial-for-android">USB Serial |  | ||||||
|  *      for Android project page</a> |  | ||||||
|  * @see <a href="http://www.ftdichip.com/">FTDI Homepage</a> |  | ||||||
|  * @see <a href="http://www.intra2net.com/en/developer/libftdi">libftdi</a> |  | ||||||
|  */ |  */ | ||||||
|  | 
 | ||||||
| public class FtdiSerialDriver implements UsbSerialDriver { | public class FtdiSerialDriver implements UsbSerialDriver { | ||||||
| 
 | 
 | ||||||
|  |     private static final String TAG = FtdiSerialPort.class.getSimpleName(); | ||||||
|  | 
 | ||||||
|     private final UsbDevice mDevice; |     private final UsbDevice mDevice; | ||||||
|     private final List<UsbSerialPort> mPorts; |     private final List<UsbSerialPort> mPorts; | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * FTDI chip types. |  | ||||||
|      */ |  | ||||||
|     private static enum DeviceType { |  | ||||||
|         TYPE_BM, TYPE_AM, TYPE_2232C, TYPE_R, TYPE_2232H, TYPE_4232H; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public FtdiSerialDriver(UsbDevice device) { |     public FtdiSerialDriver(UsbDevice device) { | ||||||
|         mDevice = device; |         mDevice = device; | ||||||
|         mPorts = new ArrayList<>(); |         mPorts = new ArrayList<>(); | ||||||
| @ -120,96 +70,35 @@ public class FtdiSerialDriver implements UsbSerialDriver { | |||||||
| 
 | 
 | ||||||
|     public class FtdiSerialPort extends CommonUsbSerialPort { |     public class FtdiSerialPort extends CommonUsbSerialPort { | ||||||
| 
 | 
 | ||||||
|         private static final int USB_TYPE_STANDARD = 0x00 << 5; |  | ||||||
|         private static final int USB_TYPE_CLASS = 0x00 << 5; |  | ||||||
|         private static final int USB_TYPE_VENDOR = 0x00 << 5; |  | ||||||
|         private static final int USB_TYPE_RESERVED = 0x00 << 5; |  | ||||||
| 
 |  | ||||||
|         private static final int USB_RECIP_DEVICE = 0x00; |  | ||||||
|         private static final int USB_RECIP_INTERFACE = 0x01; |  | ||||||
|         private static final int USB_RECIP_ENDPOINT = 0x02; |  | ||||||
|         private static final int USB_RECIP_OTHER = 0x03; |  | ||||||
| 
 |  | ||||||
|         private static final int USB_ENDPOINT_IN = 0x80; |  | ||||||
|         private static final int USB_ENDPOINT_OUT = 0x00; |  | ||||||
| 
 |  | ||||||
|         private static final int USB_WRITE_TIMEOUT_MILLIS = 5000; |         private static final int USB_WRITE_TIMEOUT_MILLIS = 5000; | ||||||
|         private static final int USB_READ_TIMEOUT_MILLIS = 5000; |         private static final int READ_HEADER_LENGTH = 2; // contains MODEM_STATUS | ||||||
| 
 | 
 | ||||||
|         // From ftdi.h |         private static final int REQTYPE_HOST_TO_DEVICE = UsbConstants.USB_TYPE_VENDOR | UsbConstants.USB_DIR_OUT; | ||||||
|         /** |         private static final int REQTYPE_DEVICE_TO_HOST = UsbConstants.USB_TYPE_VENDOR | UsbConstants.USB_DIR_IN; | ||||||
|          * Reset the port. |  | ||||||
|          */ |  | ||||||
|         private static final int SIO_RESET_REQUEST = 0; |  | ||||||
| 
 | 
 | ||||||
|         /** |         private static final int RESET_REQUEST = 0; | ||||||
|          * Set the modem control register. |         private static final int MODEM_CONTROL_REQUEST = 1; | ||||||
|          */ |         private static final int SET_BAUD_RATE_REQUEST = 3; | ||||||
|         private static final int SIO_MODEM_CTRL_REQUEST = 1; |         private static final int SET_DATA_REQUEST = 4; | ||||||
|  |         private static final int GET_MODEM_STATUS_REQUEST = 5; | ||||||
|  |         private static final int SET_LATENCY_TIMER_REQUEST = 9; | ||||||
|  |         private static final int GET_LATENCY_TIMER_REQUEST = 10; | ||||||
| 
 | 
 | ||||||
|         /** |         private static final int MODEM_CONTROL_DTR_ENABLE = 0x0101; | ||||||
|          * Set flow control register. |         private static final int MODEM_CONTROL_DTR_DISABLE = 0x0100; | ||||||
|          */ |         private static final int MODEM_CONTROL_RTS_ENABLE = 0x0202; | ||||||
|         private static final int SIO_SET_FLOW_CTRL_REQUEST = 2; |         private static final int MODEM_CONTROL_RTS_DISABLE = 0x0200; | ||||||
|  |         private static final int MODEM_STATUS_CTS = 0x10; | ||||||
|  |         private static final int MODEM_STATUS_DSR = 0x20; | ||||||
|  |         private static final int MODEM_STATUS_RI = 0x40; | ||||||
|  |         private static final int MODEM_STATUS_CD = 0x80; | ||||||
|  |         private static final int RESET_ALL = 0; | ||||||
|  |         private static final int RESET_PURGE_RX = 1; | ||||||
|  |         private static final int RESET_PURGE_TX = 2; | ||||||
| 
 | 
 | ||||||
|         private static final int SIO_SET_DTR_HIGH = 0x0101; |         private boolean baudRateWithPort = false; | ||||||
|         private static final int SIO_SET_DTR_LOW = 0x0100; |         private boolean dtr = false; | ||||||
|         private static final int SIO_SET_RTS_HIGH = 0x0202; |         private boolean rts = false; | ||||||
|         private static final int SIO_SET_RTS_LOW = 0x0200; |  | ||||||
| 
 |  | ||||||
|         /** |  | ||||||
|          * Set baud rate. |  | ||||||
|          */ |  | ||||||
|         private static final int SIO_SET_BAUD_RATE_REQUEST = 3; |  | ||||||
| 
 |  | ||||||
|         /** |  | ||||||
|          * Set the data characteristics of the port. |  | ||||||
|          */ |  | ||||||
|         private static final int SIO_SET_DATA_REQUEST = 4; |  | ||||||
| 
 |  | ||||||
|         private static final int SIO_RESET_SIO = 0; |  | ||||||
|         private static final int SIO_RESET_PURGE_RX = 1; // RX @ FTDI device = write @ usb-serial-for-android library |  | ||||||
|         private static final int SIO_RESET_PURGE_TX = 2; |  | ||||||
| 
 |  | ||||||
|         /** |  | ||||||
|          * Get modem status. |  | ||||||
|          */ |  | ||||||
|         private static final int SIO_GET_MODEM_STATUS_REQUEST = 5; |  | ||||||
| 
 |  | ||||||
|         private static final int SIO_MODEM_STATUS_CTS = 0x10; |  | ||||||
|         private static final int SIO_MODEM_STATUS_DSR = 0x20; |  | ||||||
|         private static final int SIO_MODEM_STATUS_RI = 0x40; |  | ||||||
|         private static final int SIO_MODEM_STATUS_RLSD = 0x80; |  | ||||||
| 
 |  | ||||||
|         /** |  | ||||||
|          * Set the latency timer. |  | ||||||
|          */ |  | ||||||
|         private static final int SIO_SET_LATENCY_TIMER_REQUEST = 9; |  | ||||||
| 
 |  | ||||||
|         /** |  | ||||||
|          * Get the latency timer. |  | ||||||
|          */ |  | ||||||
|         private static final int SIO_GET_LATENCY_TIMER_REQUEST = 10; |  | ||||||
| 
 |  | ||||||
|         private static final int FTDI_DEVICE_OUT_REQTYPE = |  | ||||||
|                 UsbConstants.USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT; |  | ||||||
| 
 |  | ||||||
|         private static final int FTDI_DEVICE_IN_REQTYPE = |  | ||||||
|                 UsbConstants.USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN; |  | ||||||
| 
 |  | ||||||
|         /** |  | ||||||
|          * Length of the modem status header, transmitted with every read. |  | ||||||
|          */ |  | ||||||
|         private static final int MODEM_STATUS_HEADER_LENGTH = 2; |  | ||||||
| 
 |  | ||||||
|         private final String TAG = FtdiSerialDriver.class.getSimpleName(); |  | ||||||
| 
 |  | ||||||
|         private DeviceType mType; |  | ||||||
| 
 |  | ||||||
|         private int mIndex = 0; |  | ||||||
| 
 |  | ||||||
|         private boolean mDtrState = false; |  | ||||||
|         private boolean mRtsState = false; |  | ||||||
| 
 | 
 | ||||||
|         public FtdiSerialPort(UsbDevice device, int portNumber) { |         public FtdiSerialPort(UsbDevice device, int portNumber) { | ||||||
|             super(device, portNumber); |             super(device, portNumber); | ||||||
| @ -220,95 +109,38 @@ public class FtdiSerialDriver implements UsbSerialDriver { | |||||||
|             return FtdiSerialDriver.this; |             return FtdiSerialDriver.this; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /** |  | ||||||
|          * Filter FTDI status bytes from buffer |  | ||||||
|          * @param buffer The source buffer (which contains status bytes) |  | ||||||
|          *        buffer The destination buffer to write the status bytes into (can be src) |  | ||||||
|          * @param totalBytesRead Number of bytes read to src |  | ||||||
|          * @return The number of payload bytes |  | ||||||
|          */ |  | ||||||
|         @Override |  | ||||||
|         protected int readFilter(byte[] buffer, int totalBytesRead) throws IOException { |  | ||||||
|             if (totalBytesRead < MODEM_STATUS_HEADER_LENGTH) { |  | ||||||
|                 throw new IOException("Expected at least " + MODEM_STATUS_HEADER_LENGTH + " bytes"); |  | ||||||
|             } |  | ||||||
|             int maxPacketSize = mReadEndpoint.getMaxPacketSize(); |  | ||||||
|             final int packetsCount = (totalBytesRead + maxPacketSize -1 )/ maxPacketSize; |  | ||||||
|             for (int packetIdx = 0; packetIdx < packetsCount; ++packetIdx) { |  | ||||||
|                 final int count = (packetIdx == (packetsCount - 1)) |  | ||||||
|                         ? totalBytesRead - packetIdx * maxPacketSize - MODEM_STATUS_HEADER_LENGTH |  | ||||||
|                         : maxPacketSize - MODEM_STATUS_HEADER_LENGTH; |  | ||||||
|                 if (count > 0) { |  | ||||||
|                     System.arraycopy(buffer, packetIdx * maxPacketSize + MODEM_STATUS_HEADER_LENGTH, |  | ||||||
|                                      buffer, packetIdx * (maxPacketSize - MODEM_STATUS_HEADER_LENGTH), |  | ||||||
|                                      count); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             return totalBytesRead - (packetsCount * 2); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         private void reset() throws IOException { |  | ||||||
|             // TODO(mikey): autodetect. |  | ||||||
|             mType = DeviceType.TYPE_R; |  | ||||||
|             if(mDevice.getInterfaceCount() > 1) { |  | ||||||
|                 mIndex = mPortNumber + 1; |  | ||||||
|                 if (mDevice.getInterfaceCount() == 2) |  | ||||||
|                     mType = DeviceType.TYPE_2232H; |  | ||||||
|                 if (mDevice.getInterfaceCount() == 4) |  | ||||||
|                     mType = DeviceType.TYPE_4232H; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE, SIO_RESET_REQUEST, |  | ||||||
|                     SIO_RESET_SIO, mIndex, null, 0, USB_WRITE_TIMEOUT_MILLIS); |  | ||||||
|             if (result != 0) { |  | ||||||
|                 throw new IOException("Reset failed: result=" + result); |  | ||||||
|             } |  | ||||||
|             mDtrState = false; |  | ||||||
|             mRtsState = false; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         public void setLatencyTimer(int latencyTime) throws IOException { |  | ||||||
|             int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE, SIO_SET_LATENCY_TIMER_REQUEST, |  | ||||||
|                     latencyTime, mIndex, null, 0, USB_WRITE_TIMEOUT_MILLIS); |  | ||||||
|             if (result != 0) { |  | ||||||
|                 throw new IOException("Set latency timer failed: result=" + result); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         public int getLatencyTimer() throws IOException { |  | ||||||
|             byte[] data = new byte[1]; |  | ||||||
|             int result = mConnection.controlTransfer(FTDI_DEVICE_IN_REQTYPE, SIO_GET_LATENCY_TIMER_REQUEST, |  | ||||||
|                     0, mIndex, data, data.length, USB_WRITE_TIMEOUT_MILLIS); |  | ||||||
|             if (result != 1) { |  | ||||||
|                 throw new IOException("Get latency timer failed: result=" + result); |  | ||||||
|             } |  | ||||||
|             return data[0]; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         private int getModemStatus() throws IOException { |  | ||||||
|             byte[] data = new byte[2]; |  | ||||||
|             int result = mConnection.controlTransfer(FTDI_DEVICE_IN_REQTYPE, SIO_GET_MODEM_STATUS_REQUEST, |  | ||||||
|                     0, mIndex, data, data.length, USB_WRITE_TIMEOUT_MILLIS); |  | ||||||
|             if (result != 2) { |  | ||||||
|                 throw new IOException("Get modem statusfailed: result=" + result); |  | ||||||
|             } |  | ||||||
|             return data[0]; |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         @Override |         @Override | ||||||
|         protected void openInt(UsbDeviceConnection connection) throws IOException { |         protected void openInt(UsbDeviceConnection connection) throws IOException { | ||||||
|             if (connection.claimInterface(mDevice.getInterface(mPortNumber), true)) { |             if (!connection.claimInterface(mDevice.getInterface(mPortNumber), true)) { | ||||||
|                 Log.d(TAG, "claimInterface " + mPortNumber + " SUCCESS"); |                 throw new IOException("Could not claim interface " + mPortNumber); | ||||||
|             } else { |  | ||||||
|                 throw new IOException("Error claiming interface " + mPortNumber); |  | ||||||
|             } |             } | ||||||
|             if (mDevice.getInterface(mPortNumber).getEndpointCount() < 2) { |             if (mDevice.getInterface(mPortNumber).getEndpointCount() < 2) { | ||||||
|                 throw new IOException("Insufficient number of endpoints (" + |                 throw new IOException("Not enough endpoints"); | ||||||
|                         mDevice.getInterface(mPortNumber).getEndpointCount() + ")"); |  | ||||||
|             } |             } | ||||||
|             mReadEndpoint = mDevice.getInterface(mPortNumber).getEndpoint(0); |             mReadEndpoint = mDevice.getInterface(mPortNumber).getEndpoint(0); | ||||||
|             mWriteEndpoint = mDevice.getInterface(mPortNumber).getEndpoint(1); |             mWriteEndpoint = mDevice.getInterface(mPortNumber).getEndpoint(1); | ||||||
|             reset(); | 
 | ||||||
|  |             int result = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, RESET_REQUEST, | ||||||
|  |                     RESET_ALL, mPortNumber+1, null, 0, USB_WRITE_TIMEOUT_MILLIS); | ||||||
|  |             if (result != 0) { | ||||||
|  |                 throw new IOException("Reset failed: result=" + result); | ||||||
|  |             } | ||||||
|  |             result = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, MODEM_CONTROL_REQUEST, | ||||||
|  |                     (dtr ? MODEM_CONTROL_DTR_ENABLE : MODEM_CONTROL_DTR_DISABLE) | | ||||||
|  |                             (rts ? MODEM_CONTROL_RTS_ENABLE : MODEM_CONTROL_RTS_DISABLE), | ||||||
|  |                     mPortNumber+1, null, 0, USB_WRITE_TIMEOUT_MILLIS); | ||||||
|  |             if (result != 0) { | ||||||
|  |                 throw new IOException("Init RTS,DTR failed: result=" + result); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // mDevice.getVersion() would require API 23 | ||||||
|  |             byte[] rawDescriptors = connection.getRawDescriptors(); | ||||||
|  |             if(rawDescriptors == null || rawDescriptors.length < 14) { | ||||||
|  |                 throw new IOException("Could not get device descriptors"); | ||||||
|  |             } | ||||||
|  |             int deviceType = rawDescriptors[13]; | ||||||
|  |             baudRateWithPort = deviceType == 7 || deviceType == 8 || deviceType == 9; // ...H devices | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         @Override |         @Override | ||||||
| @ -318,18 +150,69 @@ public class FtdiSerialDriver implements UsbSerialDriver { | |||||||
|             } catch(Exception ignored) {} |             } catch(Exception ignored) {} | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         private int setBaudRate(int baudRate) throws IOException { |         @Override | ||||||
|             long[] vals = convertBaudrate(baudRate); |         protected int readFilter(byte[] buffer, int totalBytesRead) throws IOException { | ||||||
|             long actualBaudrate = vals[0]; |             final int maxPacketSize = mReadEndpoint.getMaxPacketSize(); | ||||||
|             long index = vals[1]; |             int destPos = 0; | ||||||
|             long value = vals[2]; |             for(int srcPos = 0; srcPos < totalBytesRead; srcPos += maxPacketSize) { | ||||||
|             int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE, |                 int length = Math.min(srcPos + maxPacketSize, totalBytesRead) - (srcPos + READ_HEADER_LENGTH); | ||||||
|                     SIO_SET_BAUD_RATE_REQUEST, (int) value, (int) index, |                 if (length < 0) | ||||||
|                     null, 0, USB_WRITE_TIMEOUT_MILLIS); |                     throw new IOException("Expected at least " + READ_HEADER_LENGTH + " bytes"); | ||||||
|  |                 System.arraycopy(buffer, srcPos + READ_HEADER_LENGTH, buffer, destPos, length); | ||||||
|  |                 destPos += length; | ||||||
|  |             } | ||||||
|  |             return destPos; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private void setBaudrate(int baudRate) throws IOException { | ||||||
|  |             int divisor, subdivisor, effectiveBaudRate; | ||||||
|  |             if (baudRate > 3500000) { | ||||||
|  |                 throw new IOException("Baud rate to high"); | ||||||
|  |             } else if(baudRate >= 2500000) { | ||||||
|  |                 divisor = 0; | ||||||
|  |                 subdivisor = 0; | ||||||
|  |                 effectiveBaudRate = 3000000; | ||||||
|  |             } else if(baudRate >= 1750000) { | ||||||
|  |                 divisor = 1; | ||||||
|  |                 subdivisor = 0; | ||||||
|  |                 effectiveBaudRate = 2000000; | ||||||
|  |             } else { | ||||||
|  |                 divisor = (24000000 << 1) / baudRate; | ||||||
|  |                 divisor = (divisor + 1) >> 1; // round | ||||||
|  |                 subdivisor = divisor & 0x07; | ||||||
|  |                 divisor >>= 3; | ||||||
|  |                 if (divisor > 0x3fff) // exceeds bit 13 at 183 baud | ||||||
|  |                     throw new IOException("Baud rate to low"); | ||||||
|  |                 effectiveBaudRate = (24000000 << 1) / ((divisor << 3) + subdivisor); | ||||||
|  |                 effectiveBaudRate = (effectiveBaudRate +1) >> 1; | ||||||
|  |             } | ||||||
|  |             double baudRateError = Math.abs(1.0 - (effectiveBaudRate / (double)baudRate)); | ||||||
|  |             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)); | ||||||
|  |             int value = divisor; | ||||||
|  |             int index = 0; | ||||||
|  |             switch(subdivisor) { | ||||||
|  |                 case 0:                              break; // 16,15,14 = 000 - sub-integer divisor = 0 | ||||||
|  |                 case 4: value |= 0x4000;             break; // 16,15,14 = 001 - sub-integer divisor = 0.5 | ||||||
|  |                 case 2: value |= 0x8000;             break; // 16,15,14 = 010 - sub-integer divisor = 0.25 | ||||||
|  |                 case 1: value |= 0xc000;             break; // 16,15,14 = 011 - sub-integer divisor = 0.125 | ||||||
|  |                 case 3: value |= 0x0000; index |= 1; break; // 16,15,14 = 100 - sub-integer divisor = 0.375 | ||||||
|  |                 case 5: value |= 0x4000; index |= 1; break; // 16,15,14 = 101 - sub-integer divisor = 0.625 | ||||||
|  |                 case 6: value |= 0x8000; index |= 1; break; // 16,15,14 = 110 - sub-integer divisor = 0.75 | ||||||
|  |                 case 7: value |= 0xc000; index |= 1; break; // 16,15,14 = 111 - sub-integer divisor = 0.875 | ||||||
|  |             } | ||||||
|  |             if(baudRateWithPort) { | ||||||
|  |                 index <<= 8; | ||||||
|  |                 index |= mPortNumber+1; | ||||||
|  |             } | ||||||
|  |             Log.d(TAG, String.format("baud rate=%d, effective=%d, error=%.1f%%, value=0x%04x, index=0x%04x, divisor=%d, subdivisor=%d", | ||||||
|  |                     baudRate, effectiveBaudRate, baudRateError*100, value, index, divisor, subdivisor)); | ||||||
|  | 
 | ||||||
|  |             int result = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, SET_BAUD_RATE_REQUEST, | ||||||
|  |                     value, index, null, 0, USB_WRITE_TIMEOUT_MILLIS); | ||||||
|             if (result != 0) { |             if (result != 0) { | ||||||
|                 throw new IOException("Setting baudrate failed: result=" + result); |                 throw new IOException("Setting baudrate failed: result=" + result); | ||||||
|             } |             } | ||||||
|             return (int) actualBaudrate; |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         @Override |         @Override | ||||||
| @ -337,7 +220,7 @@ public class FtdiSerialDriver implements UsbSerialDriver { | |||||||
|             if(baudRate <= 0) { |             if(baudRate <= 0) { | ||||||
|                 throw new IllegalArgumentException("Invalid baud rate: " + baudRate); |                 throw new IllegalArgumentException("Invalid baud rate: " + baudRate); | ||||||
|             } |             } | ||||||
|             setBaudRate(baudRate); |             setBaudrate(baudRate); | ||||||
| 
 | 
 | ||||||
|             int config = 0; |             int config = 0; | ||||||
|             switch (dataBits) { |             switch (dataBits) { | ||||||
| @ -354,19 +237,18 @@ public class FtdiSerialDriver implements UsbSerialDriver { | |||||||
| 
 | 
 | ||||||
|             switch (parity) { |             switch (parity) { | ||||||
|                 case PARITY_NONE: |                 case PARITY_NONE: | ||||||
|                     config |= (0x00 << 8); |  | ||||||
|                     break; |                     break; | ||||||
|                 case PARITY_ODD: |                 case PARITY_ODD: | ||||||
|                     config |= (0x01 << 8); |                     config |= 0x100; | ||||||
|                     break; |                     break; | ||||||
|                 case PARITY_EVEN: |                 case PARITY_EVEN: | ||||||
|                     config |= (0x02 << 8); |                     config |= 0x200; | ||||||
|                     break; |                     break; | ||||||
|                 case PARITY_MARK: |                 case PARITY_MARK: | ||||||
|                     config |= (0x03 << 8); |                     config |= 0x300; | ||||||
|                     break; |                     break; | ||||||
|                 case PARITY_SPACE: |                 case PARITY_SPACE: | ||||||
|                     config |= (0x04 << 8); |                     config |= 0x400; | ||||||
|                     break; |                     break; | ||||||
|                 default: |                 default: | ||||||
|                     throw new IllegalArgumentException("Invalid parity: " + parity); |                     throw new IllegalArgumentException("Invalid parity: " + parity); | ||||||
| @ -374,170 +256,93 @@ public class FtdiSerialDriver implements UsbSerialDriver { | |||||||
| 
 | 
 | ||||||
|             switch (stopBits) { |             switch (stopBits) { | ||||||
|                 case STOPBITS_1: |                 case STOPBITS_1: | ||||||
|                     config |= (0x00 << 11); |  | ||||||
|                     break; |                     break; | ||||||
|                 case STOPBITS_1_5: |                 case STOPBITS_1_5: | ||||||
|                     throw new UnsupportedOperationException("Unsupported stop bits: 1.5"); |                     throw new UnsupportedOperationException("Unsupported stop bits: 1.5"); | ||||||
|                 case STOPBITS_2: |                 case STOPBITS_2: | ||||||
|                     config |= (0x02 << 11); |                     config |= 0x1000; | ||||||
|                     break; |                     break; | ||||||
|                 default: |                 default: | ||||||
|                     throw new IllegalArgumentException("Invalid stop bits: " + stopBits); |                     throw new IllegalArgumentException("Invalid stop bits: " + stopBits); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE, |             int result = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, SET_DATA_REQUEST, | ||||||
|                     SIO_SET_DATA_REQUEST, config, mIndex, |                     config, mPortNumber+1,null, 0, USB_WRITE_TIMEOUT_MILLIS); | ||||||
|                     null, 0, USB_WRITE_TIMEOUT_MILLIS); |  | ||||||
|             if (result != 0) { |             if (result != 0) { | ||||||
|                 throw new IOException("Setting parameters failed: result=" + result); |                 throw new IOException("Setting parameters failed: result=" + result); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         private long[] convertBaudrate(int baudrate) { |         private int getStatus() throws IOException { | ||||||
|             // TODO(mikey): Braindead transcription of libfti method.  Clean up, |             byte[] data = new byte[2]; | ||||||
|             // using more idiomatic Java where possible. |             int result = mConnection.controlTransfer(REQTYPE_DEVICE_TO_HOST, GET_MODEM_STATUS_REQUEST, | ||||||
|             int divisor = 24000000 / baudrate; |                     0, mPortNumber+1, data, data.length, USB_WRITE_TIMEOUT_MILLIS); | ||||||
|             int bestDivisor = 0; |             if (result != 2) { | ||||||
|             int bestBaud = 0; |                 throw new IOException("Get modem status failed: result=" + result); | ||||||
|             int bestBaudDiff = 0; |  | ||||||
|             int fracCode[] = { |  | ||||||
|                     0, 3, 2, 4, 1, 5, 6, 7 |  | ||||||
|             }; |  | ||||||
| 
 |  | ||||||
|             for (int i = 0; i < 2; i++) { |  | ||||||
|                 int tryDivisor = divisor + i; |  | ||||||
|                 int baudEstimate; |  | ||||||
|                 int baudDiff; |  | ||||||
| 
 |  | ||||||
|                 if (tryDivisor <= 8) { |  | ||||||
|                     // Round up to minimum supported divisor |  | ||||||
|                     tryDivisor = 8; |  | ||||||
|                 } else if (mType != DeviceType.TYPE_AM && tryDivisor < 12) { |  | ||||||
|                     // BM doesn't support divisors 9 through 11 inclusive |  | ||||||
|                     tryDivisor = 12; |  | ||||||
|                 } else if (divisor < 16) { |  | ||||||
|                     // AM doesn't support divisors 9 through 15 inclusive |  | ||||||
|                     tryDivisor = 16; |  | ||||||
|                 } else { |  | ||||||
|                     if (mType == DeviceType.TYPE_AM) { |  | ||||||
|                         // TODO |  | ||||||
|                     } else { |  | ||||||
|                         if (tryDivisor > 0x1FFFF) { |  | ||||||
|                             // Round down to maximum supported divisor value (for |  | ||||||
|                             // BM) |  | ||||||
|                             tryDivisor = 0x1FFFF; |  | ||||||
|             } |             } | ||||||
|                     } |             return data[0]; | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 // Get estimated baud rate (to nearest integer) |  | ||||||
|                 baudEstimate = (24000000 + (tryDivisor / 2)) / tryDivisor; |  | ||||||
| 
 |  | ||||||
|                 // Get absolute difference from requested baud rate |  | ||||||
|                 if (baudEstimate < baudrate) { |  | ||||||
|                     baudDiff = baudrate - baudEstimate; |  | ||||||
|                 } else { |  | ||||||
|                     baudDiff = baudEstimate - baudrate; |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 if (i == 0 || baudDiff < bestBaudDiff) { |  | ||||||
|                     // Closest to requested baud rate so far |  | ||||||
|                     bestDivisor = tryDivisor; |  | ||||||
|                     bestBaud = baudEstimate; |  | ||||||
|                     bestBaudDiff = baudDiff; |  | ||||||
|                     if (baudDiff == 0) { |  | ||||||
|                         // Spot on! No point trying |  | ||||||
|                         break; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             // Encode the best divisor value |  | ||||||
|             long encodedDivisor = (bestDivisor >> 3) | (fracCode[bestDivisor & 7] << 14); |  | ||||||
|             // Deal with special cases for encoded value |  | ||||||
|             if (encodedDivisor == 1) { |  | ||||||
|                 encodedDivisor = 0; // 3000000 baud |  | ||||||
|             } else if (encodedDivisor == 0x4001) { |  | ||||||
|                 encodedDivisor = 1; // 2000000 baud (BM only) |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             // Split into "value" and "index" values |  | ||||||
|             long value = encodedDivisor & 0xFFFF; |  | ||||||
|             long index; |  | ||||||
|             if (mType == DeviceType.TYPE_2232C || mType == DeviceType.TYPE_2232H |  | ||||||
|                     || mType == DeviceType.TYPE_4232H) { |  | ||||||
|                 index = (encodedDivisor >> 8) & 0xff00; |  | ||||||
|                 index |= mIndex; |  | ||||||
|             } else { |  | ||||||
|                 index = (encodedDivisor >> 16) & 0xffff; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             // Return the nearest baud rate |  | ||||||
|             return new long[] { |  | ||||||
|                     bestBaud, index, value |  | ||||||
|             }; |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         @Override |         @Override | ||||||
|         public boolean getCD() throws IOException { |         public boolean getCD() throws IOException { | ||||||
|             return (getModemStatus() & SIO_MODEM_STATUS_RLSD) != 0; |             return (getStatus() & MODEM_STATUS_CD) != 0; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         @Override |         @Override | ||||||
|         public boolean getCTS() throws IOException { |         public boolean getCTS() throws IOException { | ||||||
|             return (getModemStatus() & SIO_MODEM_STATUS_CTS) != 0; |             return (getStatus() & MODEM_STATUS_CTS) != 0; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         @Override |         @Override | ||||||
|         public boolean getDSR() throws IOException { |         public boolean getDSR() throws IOException { | ||||||
|             return (getModemStatus() & SIO_MODEM_STATUS_DSR) != 0; |             return (getStatus() & MODEM_STATUS_DSR) != 0; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         @Override |         @Override | ||||||
|         public boolean getDTR() throws IOException { |         public boolean getDTR() throws IOException { | ||||||
|             return mDtrState; |             return dtr; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         @Override |         @Override | ||||||
|         public void setDTR(boolean value) throws IOException { |         public void setDTR(boolean value) throws IOException { | ||||||
|             int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE, SIO_MODEM_CTRL_REQUEST, |             int result = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, MODEM_CONTROL_REQUEST, | ||||||
|                     value ? SIO_SET_DTR_HIGH : SIO_SET_DTR_LOW, mIndex, null, 0, USB_WRITE_TIMEOUT_MILLIS); |                     value ? MODEM_CONTROL_DTR_ENABLE : MODEM_CONTROL_DTR_DISABLE, mPortNumber+1, null, 0, USB_WRITE_TIMEOUT_MILLIS); | ||||||
|             if (result != 0) { |             if (result != 0) { | ||||||
|                 throw new IOException("Set DTR failed: result=" + result); |                 throw new IOException("Set DTR failed: result=" + result); | ||||||
|             } |             } | ||||||
|             mDtrState = value; |             dtr = value; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         @Override |         @Override | ||||||
|         public boolean getRI() throws IOException { |         public boolean getRI() throws IOException { | ||||||
|             return (getModemStatus() & SIO_MODEM_STATUS_RI) != 0; |             return (getStatus() & MODEM_STATUS_RI) != 0; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         @Override |         @Override | ||||||
|         public boolean getRTS() throws IOException { |         public boolean getRTS() throws IOException { | ||||||
|             return mRtsState; |             return rts; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         @Override |         @Override | ||||||
|         public void setRTS(boolean value) throws IOException { |         public void setRTS(boolean value) throws IOException { | ||||||
|             int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE, SIO_MODEM_CTRL_REQUEST, |             int result = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, MODEM_CONTROL_REQUEST, | ||||||
|                     value ? SIO_SET_RTS_HIGH : SIO_SET_RTS_LOW, mIndex, null, 0, USB_WRITE_TIMEOUT_MILLIS); |                     value ? MODEM_CONTROL_RTS_ENABLE : MODEM_CONTROL_RTS_DISABLE, mPortNumber+1, null, 0, USB_WRITE_TIMEOUT_MILLIS); | ||||||
|             if (result != 0) { |             if (result != 0) { | ||||||
|                 throw new IOException("Set DTR failed: result=" + result); |                 throw new IOException("Set DTR failed: result=" + result); | ||||||
|             } |             } | ||||||
|             mRtsState = value; |             rts = value; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         @Override |         @Override | ||||||
|         public EnumSet<ControlLine> getControlLines() throws IOException { |         public EnumSet<ControlLine> getControlLines() throws IOException { | ||||||
|             int status = getModemStatus(); |             int status = getStatus(); | ||||||
|             EnumSet<ControlLine> set = EnumSet.noneOf(ControlLine.class); |             EnumSet<ControlLine> set = EnumSet.noneOf(ControlLine.class); | ||||||
|             if(mRtsState) set.add(ControlLine.RTS); |             if(rts) set.add(ControlLine.RTS); | ||||||
|             if((status & SIO_MODEM_STATUS_CTS) != 0) set.add(ControlLine.CTS); |             if((status & MODEM_STATUS_CTS) != 0) set.add(ControlLine.CTS); | ||||||
|             if(mDtrState) set.add(ControlLine.DTR); |             if(dtr) set.add(ControlLine.DTR); | ||||||
|             if((status & SIO_MODEM_STATUS_DSR) != 0) set.add(ControlLine.DSR); |             if((status & MODEM_STATUS_DSR) != 0) set.add(ControlLine.DSR); | ||||||
|             if((status & SIO_MODEM_STATUS_RLSD) != 0) set.add(ControlLine.CD); |             if((status & MODEM_STATUS_CD) != 0) set.add(ControlLine.CD); | ||||||
|             if((status & SIO_MODEM_STATUS_RI) != 0) set.add(ControlLine.RI); |             if((status & MODEM_STATUS_RI) != 0) set.add(ControlLine.RI); | ||||||
|             return set; |             return set; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| @ -549,22 +354,41 @@ public class FtdiSerialDriver implements UsbSerialDriver { | |||||||
|         @Override |         @Override | ||||||
|         public boolean purgeHwBuffers(boolean purgeWriteBuffers, boolean purgeReadBuffers) throws IOException { |         public boolean purgeHwBuffers(boolean purgeWriteBuffers, boolean purgeReadBuffers) throws IOException { | ||||||
|             if (purgeWriteBuffers) { |             if (purgeWriteBuffers) { | ||||||
|                 int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE, SIO_RESET_REQUEST, |                 int result = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, RESET_REQUEST, | ||||||
|                         SIO_RESET_PURGE_RX, mIndex, null, 0, USB_WRITE_TIMEOUT_MILLIS); |                         RESET_PURGE_RX, mPortNumber+1, null, 0, USB_WRITE_TIMEOUT_MILLIS); | ||||||
|                 if (result != 0) { |                 if (result != 0) { | ||||||
|                     throw new IOException("purge write buffer failed: result=" + result); |                     throw new IOException("purge write buffer failed: result=" + result); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (purgeReadBuffers) { |             if (purgeReadBuffers) { | ||||||
|                 int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE, SIO_RESET_REQUEST, |                 int result = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, RESET_REQUEST, | ||||||
|                         SIO_RESET_PURGE_TX, mIndex, null, 0, USB_WRITE_TIMEOUT_MILLIS); |                         RESET_PURGE_TX, mPortNumber+1, null, 0, USB_WRITE_TIMEOUT_MILLIS); | ||||||
|                 if (result != 0) { |                 if (result != 0) { | ||||||
|                     throw new IOException("purge read buffer failed: result=" + result); |                     throw new IOException("purge read buffer failed: result=" + result); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         public void setLatencyTimer(int latencyTime) throws IOException { | ||||||
|  |             int result = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, SET_LATENCY_TIMER_REQUEST, | ||||||
|  |                     latencyTime, mPortNumber+1, null, 0, USB_WRITE_TIMEOUT_MILLIS); | ||||||
|  |             if (result != 0) { | ||||||
|  |                 throw new IOException("Set latency timer failed: result=" + result); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public int getLatencyTimer() throws IOException { | ||||||
|  |             byte[] data = new byte[1]; | ||||||
|  |             int result = mConnection.controlTransfer(REQTYPE_DEVICE_TO_HOST, GET_LATENCY_TIMER_REQUEST, | ||||||
|  |                     0, mPortNumber+1, data, data.length, USB_WRITE_TIMEOUT_MILLIS); | ||||||
|  |             if (result != 1) { | ||||||
|  |                 throw new IOException("Get latency timer failed: result=" + result); | ||||||
|  |             } | ||||||
|  |             return data[0]; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static Map<Integer, int[]> getSupportedDevices() { |     public static Map<Integer, int[]> getSupportedDevices() { | ||||||
| @ -575,7 +399,6 @@ public class FtdiSerialDriver implements UsbSerialDriver { | |||||||
|                     UsbId.FTDI_FT232H, |                     UsbId.FTDI_FT232H, | ||||||
|                     UsbId.FTDI_FT2232H, |                     UsbId.FTDI_FT2232H, | ||||||
|                     UsbId.FTDI_FT4232H, |                     UsbId.FTDI_FT4232H, | ||||||
|                     UsbId.FTDI_FT231X, |  | ||||||
|                 }); |                 }); | ||||||
|         return supportedDevices; |         return supportedDevices; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -36,7 +36,6 @@ public final class UsbId { | |||||||
|     public static final int FTDI_FT2232H = 0x6010; |     public static final int FTDI_FT2232H = 0x6010; | ||||||
|     public static final int FTDI_FT4232H = 0x6011; |     public static final int FTDI_FT4232H = 0x6011; | ||||||
|     public static final int FTDI_FT232H = 0x6014; |     public static final int FTDI_FT232H = 0x6014; | ||||||
|     public static final int FTDI_FT231X = 0x6015; |  | ||||||
| 
 | 
 | ||||||
|     public static final int VENDOR_ATMEL = 0x03EB; |     public static final int VENDOR_ATMEL = 0x03EB; | ||||||
|     public static final int ATMEL_LUFA_CDC_DEMO_APP = 0x2044; |     public static final int ATMEL_LUFA_CDC_DEMO_APP = 0x2044; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user