Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix more boards #497

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion ClientLib/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ dependencies {
//MP4 generation library
compile 'com.googlecode.mp4parser:isoparser:1.1.7'

compile 'org.droidplanner.android:usb-serial-android:0.1.0'

debugCompile project(':Mavlink')
// sitlCompile project(':Mavlink')
Expand Down
19 changes: 19 additions & 0 deletions ClientLib/src/main/java/com/hoho/android/usbserial/BuildInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.hoho.android.usbserial;

/**
* Static container of information about this library.
*/
public final class BuildInfo {

/**
* The current version of this library. Values are of the form
* "major.minor.micro[-suffix]". A suffix of "-pre" indicates a pre-release
* of the version preceeding it.
*/
public static final String VERSION = "0.2.0-pre";

private BuildInfo() {
throw new IllegalStateException("Non-instantiable class.");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,336 @@
package com.hoho.android.usbserial.driver;

import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.os.Build;
import android.util.Log;
import android.util.SparseArray;

import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;

/**
* USB CDC/ACM serial driver implementation.
*
* @author mike wakerly ([email protected])
* @see <a
* href="http://www.usb.org/developers/devclass_docs/usbcdc11.pdf">Universal
* Serial Bus Class Definitions for Communication Devices, v1.1</a>
*/
public class CdcAcmSerialDriver extends CommonUsbSerialDriver {

private final String TAG = CdcAcmSerialDriver.class.getSimpleName();

private final boolean mEnableAsyncReads;
private UsbInterface mControlInterface;
private UsbInterface mDataInterface;

private UsbEndpoint mControlEndpoint;
private UsbEndpoint mReadEndpoint;
private UsbEndpoint mWriteEndpoint;

private boolean mRts = false;
private boolean mDtr = false;

private static final int USB_RECIP_INTERFACE = 0x01;
private static final int USB_RT_ACM = UsbConstants.USB_TYPE_CLASS | USB_RECIP_INTERFACE;

private static final int SET_LINE_CODING = 0x20; // USB CDC 1.1 section 6.2
private static final int GET_LINE_CODING = 0x21;
private static final int SET_CONTROL_LINE_STATE = 0x22;
private static final int SEND_BREAK = 0x23;

public CdcAcmSerialDriver(UsbDevice device, UsbDeviceConnection connection) {
super(device, connection);
mEnableAsyncReads = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1);
}

@Override
public void open() throws IOException {
Log.d(TAG, "device " + mDevice);
mControlInterface = null;
mDataInterface = null;
mWriteEndpoint = null;
mReadEndpoint = null;

// locate all needed interfaces
for(int i = 0; i < mDevice.getInterfaceCount();i++){
UsbInterface iface = mDevice.getInterface(i);

switch(iface.getInterfaceClass()){
case UsbConstants.USB_CLASS_COMM:
mControlInterface = iface;
Log.d(TAG, "control iface=" + iface);
break;
case UsbConstants.USB_CLASS_CDC_DATA:
mDataInterface = iface;
Log.d(TAG, "data iface=" + iface);
break;
default:
Log.d(TAG, "skipping iface=" + iface);
break;
}
}

// failback to the old way
if(mControlInterface == null) {
mControlInterface = mDevice.getInterface(0);
Log.d(TAG, "Failback: Control iface=" + mControlInterface);
}

if (!mConnection.claimInterface(mControlInterface, true)) {
throw new IOException("Could not claim control interface.");
}

mControlEndpoint = mControlInterface.getEndpoint(0);
Log.d(TAG, "Control endpoint: " + mControlEndpoint);


if(mDataInterface == null) {
mDataInterface = mDevice.getInterface(1);
Log.d(TAG, "Failback: data iface=" + mDataInterface);
}

if (!mConnection.claimInterface(mDataInterface, true)) {
throw new IOException("Could not claim data interface.");
}

for(int i = 0; i < mDataInterface.getEndpointCount(); i++) {
UsbEndpoint endpoint = mDataInterface.getEndpoint(i);
switch (endpoint.getDirection()) {
case UsbConstants.USB_DIR_OUT:
mWriteEndpoint = endpoint;
Log.d(TAG, "Write endpoint: " + mWriteEndpoint);
break;
case UsbConstants.USB_DIR_IN:
mReadEndpoint = endpoint;
Log.d(TAG, "Read endpoint: " + mReadEndpoint);
break;
}
}

if(mReadEndpoint == null || mWriteEndpoint == null){
// failback to the old method
mReadEndpoint = mDataInterface.getEndpoint(0);
Log.d(TAG, "Read endpoint direction: " + mReadEndpoint.getDirection());
mWriteEndpoint = mDataInterface.getEndpoint(1);
Log.d(TAG, "Write endpoint direction: " + mWriteEndpoint.getDirection());
}
}


private int sendAcmControlMessage(int request, int value, byte[] buf) {
return mConnection.controlTransfer(
USB_RT_ACM, request, value, 0, buf, buf != null ? buf.length : 0, 5000);
}

@Override
public void close() throws IOException {
mConnection.close();
}

@Override
public int read(byte[] dest, int timeoutMillis) throws IOException {
final int numBytesRead;
synchronized (mReadBufferLock) {
int readAmt = Math.min(dest.length, mReadBuffer.length);
numBytesRead = mConnection.bulkTransfer(mReadEndpoint, mReadBuffer, readAmt,
timeoutMillis);
if (numBytesRead < 0) {
// This sucks: we get -1 on timeout, not 0 as preferred.
// We *should* use UsbRequest, except it has a bug/api oversight
// where there is no way to determine the number of bytes read
// in response :\ -- http://b.android.com/28023
return 0;
}
System.arraycopy(mReadBuffer, 0, dest, 0, numBytesRead);
}
return numBytesRead;
}

@Override
public int write(byte[] src, int timeoutMillis) throws IOException {
// TODO(mikey): Nearly identical to FtdiSerial write. Refactor.
int offset = 0;

while (offset < src.length) {
final int writeLength;
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(mWriteEndpoint, writeBuffer, writeLength,
timeoutMillis);
}
if (amtWritten <= 0) {
throw new IOException("Error writing " + writeLength
+ " bytes at offset " + offset + " length=" + src.length);
}

//Log.d(TAG, "Wrote amt=" + amtWritten + " attempted=" + writeLength);
offset += amtWritten;
}
return offset;
}

@Override
public void setParameters(int baudRate, int dataBits, int stopBits, int parity) {
byte stopBitsByte;
switch (stopBits) {
case STOPBITS_1: stopBitsByte = 0; break;
case STOPBITS_1_5: stopBitsByte = 1; break;
case STOPBITS_2: stopBitsByte = 2; break;
default: throw new IllegalArgumentException("Bad value for stopBits: " + stopBits);
}

byte parityBitesByte;
switch (parity) {
case PARITY_NONE: parityBitesByte = 0; break;
case PARITY_ODD: parityBitesByte = 1; break;
case PARITY_EVEN: parityBitesByte = 2; break;
case PARITY_MARK: parityBitesByte = 3; break;
case PARITY_SPACE: parityBitesByte = 4; break;
default: throw new IllegalArgumentException("Bad value for parity: " + parity);
}

byte[] msg = {
(byte) ( baudRate & 0xff),
(byte) ((baudRate >> 8 ) & 0xff),
(byte) ((baudRate >> 16) & 0xff),
(byte) ((baudRate >> 24) & 0xff),
stopBitsByte,
parityBitesByte,
(byte) dataBits};
sendAcmControlMessage(SET_LINE_CODING, 0, msg);
}

@Override
public boolean getCD() throws IOException {
return false; // TODO
}

@Override
public boolean getCTS() throws IOException {
return false; // TODO
}

@Override
public boolean getDSR() throws IOException {
return false; // TODO
}

@Override
public boolean getDTR() throws IOException {
return mDtr;
}

@Override
public void setDTR(boolean value) throws IOException {
mDtr = value;
setDtrRts();
}

@Override
public boolean getRI() throws IOException {
return false; // TODO
}

@Override
public boolean getRTS() throws IOException {
return mRts;
}

@Override
public void setRTS(boolean value) throws IOException {
mRts = value;
setDtrRts();
}

private void setDtrRts() {
int value = (mRts ? 0x2 : 0) | (mDtr ? 0x1 : 0);
sendAcmControlMessage(SET_CONTROL_LINE_STATE, value, null);
}

public static SparseArray<int[]> getSupportedDevices() {
final SparseArray<int[]> supportedDevices = new SparseArray<int[]>(11);
supportedDevices.put(UsbId.VENDOR_ARDUINO,
new int[] {
UsbId.ARDUINO_UNO,
UsbId.ARDUINO_UNO_R3,
UsbId.ARDUINO_MEGA_2560,
UsbId.ARDUINO_MEGA_2560_R3,
UsbId.ARDUINO_SERIAL_ADAPTER,
UsbId.ARDUINO_SERIAL_ADAPTER_R3,
UsbId.ARDUINO_MEGA_ADK,
UsbId.ARDUINO_MEGA_ADK_R3,
UsbId.ARDUINO_LEONARDO,
});
supportedDevices.put(UsbId.VENDOR_VAN_OOIJEN_TECH,
new int[] {
UsbId.VAN_OOIJEN_TECH_TEENSYDUINO_SERIAL,
});
supportedDevices.put(UsbId.VENDOR_ATMEL,
new int[] {
UsbId.ATMEL_LUFA_CDC_DEMO_APP,
});
supportedDevices.put(UsbId.VENDOR_LEAFLABS,
new int[] {
UsbId.LEAFLABS_MAPLE,
});
supportedDevices.put(UsbId.VENDOR_ARDUINO2,
new int[] {
UsbId.VAN_OOIJEN_TECH_TEENSYDUINO_SERIAL,
UsbId.PIXHAWK,
});
supportedDevices.put(Integer.valueOf(UsbId.VENDOR_PX4),
new int[] {
UsbId.DEVICE_PX4FMU,
});
supportedDevices.put(Integer.valueOf(UsbId.VENDOR_UBLOX),
new int[] {
UsbId.DEVICE_UBLOX_5,
UsbId.DEVICE_UBLOX_6,
UsbId.DEVICE_UBLOX_7,
UsbId.DEVICE_UBLOX_8,
});
supportedDevices.put(Integer.valueOf(UsbId.VENDOR_OPENPILOT),
new int[] {
UsbId.DEVICE_CC3D,
UsbId.DEVICE_REVOLUTION,
UsbId.DEVICE_SPARKY2,
UsbId.DEVICE_OPLINK,
});
supportedDevices.put(Integer.valueOf(UsbId.VENDOR_ARDUPILOT_CHIBIOS1),
new int[] {
UsbId.DEVICE_ARDUPILOT_CHIBIOS,
});
supportedDevices.put(Integer.valueOf(UsbId.VENDOR_ARDUPILOT_CHIBIOS2),
new int[] {
UsbId.DEVICE_ARDUPILOT_CHIBIOS,
});
supportedDevices.put(Integer.valueOf(UsbId.VENDOR_DRAGONLINK),
new int[] {
UsbId.DEVICE_DRAGONLINK,
});
supportedDevices.put(Integer.valueOf(UsbId.VENDOR_RADIOLINK_MINI),
new int[] {
UsbId.DEVICE_RADIOLINK_MINI,
});
return supportedDevices;
}

}
Loading