|
|
@ -18,6 +18,10 @@ |
|
|
|
* Project home page: http://code.google.com/p/usb-serial-for-android/
|
|
|
|
* Project home page: http://code.google.com/p/usb-serial-for-android/
|
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// IMPORTANT NOTE:
|
|
|
|
|
|
|
|
// This code has been modified from the original source. It now uses the FTDI driver provided by
|
|
|
|
|
|
|
|
// ftdichip.com to communicate with an FTDI device. The previous code did not work with all FTDI
|
|
|
|
|
|
|
|
// devices.
|
|
|
|
package com.hoho.android.usbserial.driver; |
|
|
|
package com.hoho.android.usbserial.driver; |
|
|
|
|
|
|
|
|
|
|
|
import android.hardware.usb.UsbConstants; |
|
|
|
import android.hardware.usb.UsbConstants; |
|
|
@ -27,12 +31,16 @@ import android.hardware.usb.UsbEndpoint; |
|
|
|
import android.hardware.usb.UsbRequest; |
|
|
|
import android.hardware.usb.UsbRequest; |
|
|
|
import android.util.Log; |
|
|
|
import android.util.Log; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import com.ftdi.j2xx.D2xxManager; |
|
|
|
|
|
|
|
import com.ftdi.j2xx.FT_Device; |
|
|
|
|
|
|
|
|
|
|
|
import java.io.IOException; |
|
|
|
import java.io.IOException; |
|
|
|
import java.nio.ByteBuffer; |
|
|
|
import java.nio.ByteBuffer; |
|
|
|
import java.util.LinkedHashMap; |
|
|
|
import java.util.LinkedHashMap; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import org.qgroundcontrol.qgchelper.UsbDeviceJNI; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* A {@link CommonUsbSerialDriver} implementation for a variety of FTDI devices |
|
|
|
* A {@link CommonUsbSerialDriver} implementation for a variety of FTDI devices |
|
|
|
* <p> |
|
|
|
* <p> |
|
|
@ -167,6 +175,8 @@ public class FtdiSerialDriver extends CommonUsbSerialDriver { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private static final boolean ENABLE_ASYNC_READS = false; |
|
|
|
private static final boolean ENABLE_ASYNC_READS = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FT_Device m_ftDev; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Filter FTDI status bytes from buffer |
|
|
|
* Filter FTDI status bytes from buffer |
|
|
|
* @param src The source buffer (which contains status bytes) |
|
|
|
* @param src The source buffer (which contains status bytes) |
|
|
@ -219,261 +229,140 @@ public class FtdiSerialDriver extends CommonUsbSerialDriver { |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void open() throws IOException { |
|
|
|
public void open() throws IOException { |
|
|
|
boolean opened = false; |
|
|
|
D2xxManager ftD2xx = null; |
|
|
|
try { |
|
|
|
try { |
|
|
|
for (int i = 0; i < mDevice.getInterfaceCount(); i++) { |
|
|
|
ftD2xx = D2xxManager.getInstance(UsbDeviceJNI.m_context); |
|
|
|
if (mConnection.claimInterface(mDevice.getInterface(i), true)) { |
|
|
|
} catch (D2xxManager.D2xxException ex) { |
|
|
|
Log.d(TAG, "claimInterface " + i + " SUCCESS"); |
|
|
|
UsbDeviceJNI.qgcLogDebug("D2xxManager.getInstance threw exception: " + ex.getMessage()); |
|
|
|
} else { |
|
|
|
} |
|
|
|
throw new IOException("Error claiming interface " + i); |
|
|
|
|
|
|
|
} |
|
|
|
if (ftD2xx == null) { |
|
|
|
} |
|
|
|
String errMsg = "Unable to retrieve D2xxManager instance."; |
|
|
|
reset(); |
|
|
|
UsbDeviceJNI.qgcLogWarning(errMsg); |
|
|
|
opened = true; |
|
|
|
throw new IOException(errMsg); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
UsbDeviceJNI.qgcLogDebug("Opened D2xxManager"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int DevCount = ftD2xx.createDeviceInfoList(UsbDeviceJNI.m_context); |
|
|
|
|
|
|
|
UsbDeviceJNI.qgcLogDebug("Found " + DevCount + " ftdi devices."); |
|
|
|
|
|
|
|
if (DevCount < 1) { |
|
|
|
|
|
|
|
throw new IOException("No FTDI Devices found"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m_ftDev = null; |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
m_ftDev = ftD2xx.openByIndex(UsbDeviceJNI.m_context, 0); |
|
|
|
|
|
|
|
} catch (NullPointerException e) { |
|
|
|
|
|
|
|
UsbDeviceJNI.qgcLogDebug("ftD2xx.openByIndex exception: " + e.getMessage()); |
|
|
|
} finally { |
|
|
|
} finally { |
|
|
|
if (!opened) { |
|
|
|
if (m_ftDev == null) { |
|
|
|
close(); |
|
|
|
throw new IOException("No FTDI Devices found"); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
UsbDeviceJNI.qgcLogDebug("Opened FTDI device."); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void close() { |
|
|
|
public void close() { |
|
|
|
mConnection.close(); |
|
|
|
if (m_ftDev != null) { |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
m_ftDev.close(); |
|
|
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
|
|
UsbDeviceJNI.qgcLogWarning("close exception: " + e.getMessage()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
m_ftDev = null; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public int read(byte[] dest, int timeoutMillis) throws IOException { |
|
|
|
public int read(byte[] dest, int timeoutMillis) throws IOException { |
|
|
|
final UsbEndpoint endpoint = mDevice.getInterface(0).getEndpoint(0); |
|
|
|
int totalBytesRead = 0; |
|
|
|
|
|
|
|
int bytesAvailable = m_ftDev.getQueueStatus(); |
|
|
|
if (ENABLE_ASYNC_READS) { |
|
|
|
|
|
|
|
final int readAmt; |
|
|
|
if (bytesAvailable > 0) { |
|
|
|
synchronized (mReadBufferLock) { |
|
|
|
bytesAvailable = Math.min(4096, bytesAvailable); |
|
|
|
// mReadBuffer is only used for maximum read size.
|
|
|
|
try { |
|
|
|
readAmt = Math.min(dest.length, mReadBuffer.length); |
|
|
|
totalBytesRead = m_ftDev.read(dest, bytesAvailable, timeoutMillis); |
|
|
|
} |
|
|
|
} catch (NullPointerException e) { |
|
|
|
|
|
|
|
final String errorMsg = "Error reading: " + e.getMessage(); |
|
|
|
final UsbRequest request = new UsbRequest(); |
|
|
|
UsbDeviceJNI.qgcLogWarning(errorMsg); |
|
|
|
request.initialize(mConnection, endpoint); |
|
|
|
throw new IOException(errorMsg, e); |
|
|
|
|
|
|
|
|
|
|
|
final ByteBuffer buf = ByteBuffer.wrap(dest); |
|
|
|
|
|
|
|
if (!request.queue(buf, readAmt)) { |
|
|
|
|
|
|
|
throw new IOException("Error queueing request."); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final UsbRequest response = mConnection.requestWait(); |
|
|
|
|
|
|
|
if (response == null) { |
|
|
|
|
|
|
|
throw new IOException("Null response"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final int payloadBytesRead = buf.position() - MODEM_STATUS_HEADER_LENGTH; |
|
|
|
|
|
|
|
if (payloadBytesRead > 0) { |
|
|
|
|
|
|
|
return payloadBytesRead; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
final int totalBytesRead; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
synchronized (mReadBufferLock) { |
|
|
|
|
|
|
|
final int readAmt = Math.min(dest.length, mReadBuffer.length); |
|
|
|
|
|
|
|
totalBytesRead = mConnection.bulkTransfer(endpoint, mReadBuffer, |
|
|
|
|
|
|
|
readAmt, timeoutMillis); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (totalBytesRead < MODEM_STATUS_HEADER_LENGTH) { |
|
|
|
|
|
|
|
throw new IOException("Expected at least " + MODEM_STATUS_HEADER_LENGTH + " bytes"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return filterStatusBytes(mReadBuffer, dest, totalBytesRead, endpoint.getMaxPacketSize()); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return totalBytesRead; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public int write(byte[] src, int timeoutMillis) throws IOException { |
|
|
|
public int write(byte[] src, int timeoutMillis) throws IOException { |
|
|
|
final UsbEndpoint endpoint = mDevice.getInterface(0).getEndpoint(1); |
|
|
|
try { |
|
|
|
int offset = 0; |
|
|
|
m_ftDev.write(src); |
|
|
|
|
|
|
|
return src.length; |
|
|
|
while (offset < src.length) { |
|
|
|
} catch (Exception e) { |
|
|
|
final int writeLength; |
|
|
|
UsbDeviceJNI.qgcLogWarning("Error writing: " + e.getMessage()); |
|
|
|
final int amtWritten; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
synchronized (mWriteBufferLock) { |
|
|
|
|
|
|
|
final byte[] writeBuffer; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
writeLength = Math.min(src.length - offset, mWriteBuffer.length); |
|
|
|
|
|
|
|
if (offset == 0) { |
|
|
|
|
|
|
|
writeBuffer = src; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
// bulkTransfer does not support offsets, make a copy.
|
|
|
|
|
|
|
|
System.arraycopy(src, offset, mWriteBuffer, 0, writeLength); |
|
|
|
|
|
|
|
writeBuffer = mWriteBuffer; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
amtWritten = mConnection.bulkTransfer(endpoint, writeBuffer, writeLength, |
|
|
|
|
|
|
|
timeoutMillis); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (amtWritten <= 0) { |
|
|
|
|
|
|
|
throw new IOException("Error writing " + writeLength |
|
|
|
|
|
|
|
+ " bytes at offset " + offset + " length=" + src.length); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Log.d(TAG, "Wrote amtWritten=" + amtWritten + " attempted=" + writeLength);
|
|
|
|
|
|
|
|
offset += amtWritten; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
return offset; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private int setBaudRate(int baudRate) throws IOException { |
|
|
|
private int setBaudRate(int baudRate) throws IOException { |
|
|
|
long[] vals = convertBaudrate(baudRate); |
|
|
|
try { |
|
|
|
long actualBaudrate = vals[0]; |
|
|
|
m_ftDev.setBaudRate(baudRate); |
|
|
|
long index = vals[1]; |
|
|
|
return baudRate; |
|
|
|
long value = vals[2]; |
|
|
|
} catch (Exception e) { |
|
|
|
int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE, |
|
|
|
UsbDeviceJNI.qgcLogWarning("Error setting baud rate: " + e.getMessage()); |
|
|
|
SIO_SET_BAUD_RATE_REQUEST, (int) value, (int) index, |
|
|
|
|
|
|
|
null, 0, USB_WRITE_TIMEOUT_MILLIS); |
|
|
|
|
|
|
|
if (result != 0) { |
|
|
|
|
|
|
|
throw new IOException("Setting baudrate failed: result=" + result); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
return (int) actualBaudrate; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void setParameters(int baudRate, int dataBits, int stopBits, int parity) |
|
|
|
public void setParameters(int baudRate, int dataBits, int stopBits, int parity) throws IOException { |
|
|
|
throws IOException { |
|
|
|
|
|
|
|
setBaudRate(baudRate); |
|
|
|
setBaudRate(baudRate); |
|
|
|
|
|
|
|
|
|
|
|
int config = dataBits; |
|
|
|
switch (dataBits) { |
|
|
|
|
|
|
|
case 7: |
|
|
|
switch (parity) { |
|
|
|
dataBits = D2xxManager.FT_DATA_BITS_7; |
|
|
|
case PARITY_NONE: |
|
|
|
break; |
|
|
|
config |= (0x00 << 8); |
|
|
|
case 8: |
|
|
|
break; |
|
|
|
default: |
|
|
|
case PARITY_ODD: |
|
|
|
dataBits = D2xxManager.FT_DATA_BITS_8; |
|
|
|
config |= (0x01 << 8); |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
case PARITY_EVEN: |
|
|
|
|
|
|
|
config |= (0x02 << 8); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case PARITY_MARK: |
|
|
|
|
|
|
|
config |= (0x03 << 8); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case PARITY_SPACE: |
|
|
|
|
|
|
|
config |= (0x04 << 8); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
throw new IllegalArgumentException("Unknown parity value: " + parity); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
switch (stopBits) { |
|
|
|
switch (stopBits) { |
|
|
|
case STOPBITS_1: |
|
|
|
default: |
|
|
|
config |= (0x00 << 11); |
|
|
|
case 0: |
|
|
|
break; |
|
|
|
stopBits = D2xxManager.FT_STOP_BITS_1; |
|
|
|
case STOPBITS_1_5: |
|
|
|
break; |
|
|
|
config |= (0x01 << 11); |
|
|
|
case 1: |
|
|
|
break; |
|
|
|
stopBits = D2xxManager.FT_STOP_BITS_2; |
|
|
|
case STOPBITS_2: |
|
|
|
break; |
|
|
|
config |= (0x02 << 11); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
throw new IllegalArgumentException("Unknown stopBits value: " + stopBits); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE, |
|
|
|
|
|
|
|
SIO_SET_DATA_REQUEST, config, 0 /* index */, |
|
|
|
|
|
|
|
null, 0, USB_WRITE_TIMEOUT_MILLIS); |
|
|
|
|
|
|
|
if (result != 0) { |
|
|
|
|
|
|
|
throw new IOException("Setting parameters failed: result=" + result); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private long[] convertBaudrate(int baudrate) { |
|
|
|
switch (parity) { |
|
|
|
// TODO(mikey): Braindead transcription of libfti method. Clean up,
|
|
|
|
default: |
|
|
|
// using more idiomatic Java where possible.
|
|
|
|
case 0: |
|
|
|
int divisor = 24000000 / baudrate; |
|
|
|
parity = D2xxManager.FT_PARITY_NONE; |
|
|
|
int bestDivisor = 0; |
|
|
|
break; |
|
|
|
int bestBaud = 0; |
|
|
|
case 1: |
|
|
|
int bestBaudDiff = 0; |
|
|
|
parity = D2xxManager.FT_PARITY_ODD; |
|
|
|
int fracCode[] = { |
|
|
|
break; |
|
|
|
0, 3, 2, 4, 1, 5, 6, 7 |
|
|
|
case 2: |
|
|
|
}; |
|
|
|
parity = D2xxManager.FT_PARITY_EVEN; |
|
|
|
|
|
|
|
break; |
|
|
|
for (int i = 0; i < 2; i++) { |
|
|
|
case 3: |
|
|
|
int tryDivisor = divisor + i; |
|
|
|
parity = D2xxManager.FT_PARITY_MARK; |
|
|
|
int baudEstimate; |
|
|
|
break; |
|
|
|
int baudDiff; |
|
|
|
case 4: |
|
|
|
|
|
|
|
parity = D2xxManager.FT_PARITY_SPACE; |
|
|
|
if (tryDivisor <= 8) { |
|
|
|
break; |
|
|
|
// 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; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
try { |
|
|
|
long value = encodedDivisor & 0xFFFF; |
|
|
|
m_ftDev.setDataCharacteristics((byte)dataBits, (byte)stopBits, (byte)parity); |
|
|
|
long index; |
|
|
|
} catch (Exception e) { |
|
|
|
if (mType == DeviceType.TYPE_2232C || mType == DeviceType.TYPE_2232H |
|
|
|
UsbDeviceJNI.qgcLogWarning("Error setDataCharacteristics: " + e.getMessage()); |
|
|
|
|| mType == DeviceType.TYPE_4232H) { |
|
|
|
|
|
|
|
index = (encodedDivisor >> 8) & 0xffff; |
|
|
|
|
|
|
|
index &= 0xFF00; |
|
|
|
|
|
|
|
index |= 0 /* TODO 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 false; |
|
|
|
return false; |
|
|
@ -515,18 +404,22 @@ public class FtdiSerialDriver extends CommonUsbSerialDriver { |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public boolean purgeHwBuffers(boolean purgeReadBuffers, boolean purgeWriteBuffers) throws IOException { |
|
|
|
public boolean purgeHwBuffers(boolean purgeReadBuffers, boolean purgeWriteBuffers) throws IOException { |
|
|
|
if (purgeReadBuffers) { |
|
|
|
if (purgeReadBuffers) { |
|
|
|
int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE, SIO_RESET_REQUEST, |
|
|
|
try { |
|
|
|
SIO_RESET_PURGE_RX, 0 /* index */, null, 0, USB_WRITE_TIMEOUT_MILLIS); |
|
|
|
m_ftDev.purge(D2xxManager.FT_PURGE_RX); |
|
|
|
if (result != 0) { |
|
|
|
} catch (Exception e) { |
|
|
|
throw new IOException("Flushing RX failed: result=" + result); |
|
|
|
String errMsg = "Error purgeHwBuffers(RX): "+ e.getMessage(); |
|
|
|
|
|
|
|
UsbDeviceJNI.qgcLogWarning(errMsg); |
|
|
|
|
|
|
|
throw new IOException(errMsg); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (purgeWriteBuffers) { |
|
|
|
if (purgeWriteBuffers) { |
|
|
|
int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE, SIO_RESET_REQUEST, |
|
|
|
try { |
|
|
|
SIO_RESET_PURGE_TX, 0 /* index */, null, 0, USB_WRITE_TIMEOUT_MILLIS); |
|
|
|
m_ftDev.purge(D2xxManager.FT_PURGE_TX); |
|
|
|
if (result != 0) { |
|
|
|
} catch (Exception e) { |
|
|
|
throw new IOException("Flushing RX failed: result=" + result); |
|
|
|
String errMsg = "Error purgeHwBuffers(TX): " + e.getMessage(); |
|
|
|
|
|
|
|
UsbDeviceJNI.qgcLogWarning(errMsg); |
|
|
|
|
|
|
|
throw new IOException(errMsg); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|