CDC generic device driver added

pull/4/head
Felipe Herranz 2014-11-10 18:13:28 +01:00
rodzic b781d3ac30
commit c1fb099ee6
19 zmienionych plików z 326 dodań i 34 usunięć

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Wyświetl plik

@ -8,6 +8,7 @@ import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbRequest;
import android.util.Log;
@Deprecated
public class BLED112SerialDevice extends UsbSerialDevice
{
private static final String CLASS_ID = BLED112SerialDevice.class.getSimpleName();
@ -45,13 +46,14 @@ public class BLED112SerialDevice extends UsbSerialDevice
private UsbEndpoint outEndpoint;
private UsbRequest requestIN;
@Deprecated
public BLED112SerialDevice(UsbDevice device, UsbDeviceConnection connection)
{
super(device, connection);
}
@Override
public void open()
public boolean open()
{
// Restart the working thread if it has been killed before and get and claim interface
restartWorkingThread();
@ -91,6 +93,8 @@ public class BLED112SerialDevice extends UsbSerialDevice
// Pass references to the threads
setThreadsParams(requestIN, outEndpoint);
return true;
}
@Override

Wyświetl plik

@ -0,0 +1,253 @@
package com.felhr.usbserial;
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.hardware.usb.UsbRequest;
import android.util.Log;
public class CDCSerialDevice extends UsbSerialDevice
{
private static final String CLASS_ID = CDCSerialDevice.class.getSimpleName();
private static final int CDC_REQTYPE_HOST2DEVICE = 0x21;
private static final int CDC_REQTYPE_DEVICE2HOST = 0xA1;
private static final int CDC_SET_LINE_CODING = 0x20;
private static final int CDC_GET_LINE_CODING = 0x21;
private static final int CDC_SET_CONTROL_LINE_STATE = 0x22;
/***
* Default Serial Configuration
* Baud rate: 115200
* Data bits: 8
* Stop bits: 1
* Parity: None
* Flow Control: Off
*/
private static final byte[] CDC_DEFAULT_LINE_CODING = new byte[] {
(byte) 0x00, // Offset 0:4 dwDTERate
(byte) 0x01,
(byte) 0xC2,
(byte) 0x00,
(byte) 0x00, // Offset 5 bCharFormat (1 Stop bit)
(byte) 0x00, // bParityType (None)
(byte) 0x08 // bDataBits (8)
};
private static final int CDC_DEFAULT_CONTROL_LINE = 0x0003;
private static final int CDC_DISCONNECT_CONTROL_LINE = 0x0002;
private UsbInterface mInterface;
private UsbEndpoint inEndpoint;
private UsbEndpoint outEndpoint;
private UsbRequest requestIN;
public CDCSerialDevice(UsbDevice device, UsbDeviceConnection connection)
{
super(device, connection);
}
@Override
public boolean open()
{
// Restart the working thread if it has been killed before and get and claim interface
restartWorkingThread();
restartWriteThread();
int interfaceCount = device.getInterfaceCount();
int iIndex = 0;
boolean keepGettingInterfaces = true;
while(iIndex <= interfaceCount -1 && keepGettingInterfaces)
{
mInterface = device.getInterface(iIndex);
if(mInterface.getInterfaceClass() != UsbConstants.USB_CLASS_CDC_DATA)
mInterface = null;
else
keepGettingInterfaces = false;
iIndex++;
}
if(mInterface == null)
{
Log.i(CLASS_ID, "There is no CDC class interface");
return false;
}
if(connection.claimInterface(mInterface, true))
{
Log.i(CLASS_ID, "Interface succesfully claimed");
}else
{
Log.i(CLASS_ID, "Interface could not be claimed");
return false;
}
// Assign endpoints
int numberEndpoints = mInterface.getEndpointCount();
for(int i=0;i<=numberEndpoints-1;i++)
{
UsbEndpoint endpoint = mInterface.getEndpoint(i);
if(endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK
&& endpoint.getDirection() == UsbConstants.USB_DIR_IN)
{
inEndpoint = endpoint;
}else if(endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK
&& endpoint.getDirection() == UsbConstants.USB_DIR_OUT)
{
outEndpoint = endpoint;
}
}
if(outEndpoint == null || inEndpoint == null)
{
Log.i(CLASS_ID, "Interface does not have an IN or OUT interface");
return false;
}
// Default Setup
if(setControlCommand(CDC_SET_LINE_CODING, 0, CDC_DEFAULT_LINE_CODING) < 0)
{
Log.i(CLASS_ID, "CDC SET LINE CODING command could not be send correctly");
return false;
}if(setControlCommand(CDC_SET_CONTROL_LINE_STATE, CDC_DEFAULT_CONTROL_LINE, null) < 0)
{
Log.i(CLASS_ID, "CDC SET CONTROL LINE STATE command could not be send correctly");
return false;
}
// Initialize UsbRequest
requestIN = new UsbRequest();
requestIN.initialize(connection, inEndpoint);
// Pass references to the threads
setThreadsParams(requestIN, outEndpoint);
return true;
}
@Override
public void close()
{
setControlCommand(CDC_SET_CONTROL_LINE_STATE, CDC_DISCONNECT_CONTROL_LINE , null);
killWorkingThread();
killWriteThread();
connection.close();
}
@Override
public void setBaudRate(int baudRate)
{
byte[] data = getLineCoding();
data[3] = (byte) (baudRate & 0xff);
data[2] = (byte) (baudRate >> 8 & 0xff);
data[1] = (byte) (baudRate >> 16 & 0xff);
data[0] = (byte) (baudRate >> 24 & 0xff);
setControlCommand(CDC_SET_LINE_CODING, 0, data);
}
@Override
public void setDataBits(int dataBits)
{
byte[] data = getLineCoding();
switch(dataBits)
{
case UsbSerialInterface.DATA_BITS_5:
data[6] = 0x05;
break;
case UsbSerialInterface.DATA_BITS_6:
data[6] = 0x06;
break;
case UsbSerialInterface.DATA_BITS_7:
data[6] = 0x07;
break;
case UsbSerialInterface.DATA_BITS_8:
data[6] = 0x08;
break;
}
setControlCommand(CDC_SET_LINE_CODING, 0, data);
}
@Override
public void setStopBits(int stopBits)
{
byte[] data = getLineCoding();
switch(stopBits)
{
case UsbSerialInterface.STOP_BITS_1:
data[4] = 0x00;
break;
case UsbSerialInterface.STOP_BITS_15:
data[4] = 0x01;
break;
case UsbSerialInterface.STOP_BITS_2:
data[4] = 0x02;
break;
}
setControlCommand(CDC_SET_LINE_CODING, 0, data);
}
@Override
public void setParity(int parity)
{
byte[] data = getLineCoding();
switch(parity)
{
case UsbSerialInterface.PARITY_NONE:
data[5] = 0x00;
break;
case UsbSerialInterface.PARITY_ODD:
data[5] = 0x01;
break;
case UsbSerialInterface.PARITY_EVEN:
data[5] = 0x02;
break;
case UsbSerialInterface.PARITY_MARK:
data[5] = 0x03;
break;
case UsbSerialInterface.PARITY_SPACE:
data[5] = 0x04;
break;
}
setControlCommand(CDC_SET_LINE_CODING, 0, data);
}
@Override
public void setFlowControl(int flowControl)
{
// TODO Auto-generated method stub
}
private int setControlCommand(int request, int value, byte[] data)
{
int dataLength = 0;
if(data != null)
{
dataLength = data.length;
}
int response = connection.controlTransfer(CDC_REQTYPE_HOST2DEVICE, request, value, 0, data, dataLength, USB_TIMEOUT);
Log.i(CLASS_ID,"Control Transfer Response: " + String.valueOf(response));
return response;
}
private byte[] getLineCoding()
{
byte[] data = new byte[7];
int response = connection.controlTransfer(CDC_REQTYPE_DEVICE2HOST, CDC_GET_LINE_CODING, 0, 0, data, data.length, USB_TIMEOUT);
Log.i(CLASS_ID,"Control Transfer Response: " + String.valueOf(response));
return data;
}
}

Wyświetl plik

@ -56,7 +56,7 @@ public class CP2102SerialDevice extends UsbSerialDevice
}
@Override
public void open()
public boolean open()
{
// Restart the working thread and writeThread if it has been killed before and get and claim interface
@ -70,6 +70,7 @@ public class CP2102SerialDevice extends UsbSerialDevice
}else
{
Log.i(CLASS_ID, "Interface could not be claimed");
return false;
}
// Assign endpoints
@ -89,11 +90,14 @@ public class CP2102SerialDevice extends UsbSerialDevice
// Default Setup
setControlCommand(CP210x_IFC_ENABLE, CP210x_UART_ENABLE, null);
if(setControlCommand(CP210x_IFC_ENABLE, CP210x_UART_ENABLE, null) < 0)
return false;
setBaudRate(DEFAULT_BAUDRATE);
setControlCommand(CP210x_SET_LINE_CTL, CP210x_LINE_CTL_DEFAULT,null);
if(setControlCommand(CP210x_SET_LINE_CTL, CP210x_LINE_CTL_DEFAULT,null) < 0)
return false;
setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
setControlCommand(CP210x_SET_MHS, CP210x_MHS_DEFAULT, null);
if(setControlCommand(CP210x_SET_MHS, CP210x_MHS_DEFAULT, null) < 0)
return false;
// Initialize UsbRequest
requestIN = new UsbRequest();
@ -101,6 +105,8 @@ public class CP2102SerialDevice extends UsbSerialDevice
// Pass references to the threads
setThreadsParams(requestIN, outEndpoint);
return true;
}
@Override

Wyświetl plik

@ -65,7 +65,7 @@ public class FTDISerialDevice extends UsbSerialDevice
}
@Override
public void open()
public boolean open()
{
// Restart the working thread and writeThread if it has been killed before and claim interface
restartWorkingThread();
@ -78,6 +78,7 @@ public class FTDISerialDevice extends UsbSerialDevice
}else
{
Log.i(CLASS_ID, "Interface could not be claimed");
return false;
}
// Assign endpoints
@ -96,13 +97,19 @@ public class FTDISerialDevice extends UsbSerialDevice
}
// Default Setup
setControlCommand(FTDI_SIO_RESET, 0x00, 0, null);
setControlCommand(FTDI_SIO_SET_DATA, FTDI_SET_DATA_DEFAULT, 0, null);
if(setControlCommand(FTDI_SIO_RESET, 0x00, 0, null) < 0)
return false;
if(setControlCommand(FTDI_SIO_SET_DATA, FTDI_SET_DATA_DEFAULT, 0, null) < 0)
return false;
currentSioSetData = FTDI_SET_DATA_DEFAULT;
setControlCommand(FTDI_SIO_MODEM_CTRL, FTDI_SET_MODEM_CTRL_DEFAULT1, 0, null);
setControlCommand(FTDI_SIO_MODEM_CTRL, FTDI_SET_MODEM_CTRL_DEFAULT2, 0, null);
setControlCommand(FTDI_SIO_SET_FLOW_CTRL, FTDI_SET_FLOW_CTRL_DEFAULT, 0, null);
setControlCommand(FTDI_SIO_SET_BAUD_RATE, FTDI_BAUDRATE_9600, 0, null);
if(setControlCommand(FTDI_SIO_MODEM_CTRL, FTDI_SET_MODEM_CTRL_DEFAULT1, 0, null) < 0)
return false;
if(setControlCommand(FTDI_SIO_MODEM_CTRL, FTDI_SET_MODEM_CTRL_DEFAULT2, 0, null) < 0)
return false;
if(setControlCommand(FTDI_SIO_SET_FLOW_CTRL, FTDI_SET_FLOW_CTRL_DEFAULT, 0, null) < 0)
return false;
if(setControlCommand(FTDI_SIO_SET_BAUD_RATE, FTDI_BAUDRATE_9600, 0, null) < 0)
return false;
// Initialize UsbRequest
requestIN = new UsbRequest();
@ -110,6 +117,8 @@ public class FTDISerialDevice extends UsbSerialDevice
// Pass references to the threads
setThreadsParams(requestIN, outEndpoint);
return true;
}
@Override

Wyświetl plik

@ -43,7 +43,7 @@ public class PL2303SerialDevice extends UsbSerialDevice
}
@Override
public void open()
public boolean open()
{
// Restart the working thread and writeThread if it has been killed before and claim interface
restartWorkingThread();
@ -56,6 +56,7 @@ public class PL2303SerialDevice extends UsbSerialDevice
}else
{
Log.i(CLASS_ID, "Interface could not be claimed");
return false;
}
// Assign endpoints
@ -74,28 +75,44 @@ public class PL2303SerialDevice extends UsbSerialDevice
//Default Setup
byte[] buf = new byte[1];
//Specific vendor stuff that I barely understand but It is on linux drivers, So I trust :)
setControlCommand(PL2303_REQTYPE_DEVICE2HOST_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x8484, 0, buf);
setControlCommand(PL2303_REQTYPE_HOST2DEVICE_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x0404, 0, null);
setControlCommand(PL2303_REQTYPE_DEVICE2HOST_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x8484, 0, buf);
setControlCommand(PL2303_REQTYPE_DEVICE2HOST_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x8383, 0, buf);
setControlCommand(PL2303_REQTYPE_DEVICE2HOST_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x8484, 0, buf);
setControlCommand(PL2303_REQTYPE_HOST2DEVICE_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x0404, 1, null);
setControlCommand(PL2303_REQTYPE_DEVICE2HOST_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x8484, 0, buf);
setControlCommand(PL2303_REQTYPE_DEVICE2HOST_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x8383, 0, buf);
setControlCommand(PL2303_REQTYPE_HOST2DEVICE_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x0000, 1, null);
setControlCommand(PL2303_REQTYPE_HOST2DEVICE_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x0001, 0, null);
setControlCommand(PL2303_REQTYPE_HOST2DEVICE_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x0002, 0x0044, null);
if(setControlCommand(PL2303_REQTYPE_DEVICE2HOST_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x8484, 0, buf) < 0)
return false;
if(setControlCommand(PL2303_REQTYPE_HOST2DEVICE_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x0404, 0, null) < 0)
return false;
if(setControlCommand(PL2303_REQTYPE_DEVICE2HOST_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x8484, 0, buf) < 0)
return false;
if(setControlCommand(PL2303_REQTYPE_DEVICE2HOST_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x8383, 0, buf) < 0)
return false;
if(setControlCommand(PL2303_REQTYPE_DEVICE2HOST_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x8484, 0, buf) < 0)
return false;
if(setControlCommand(PL2303_REQTYPE_HOST2DEVICE_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x0404, 1, null) < 0)
return false;
if(setControlCommand(PL2303_REQTYPE_DEVICE2HOST_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x8484, 0, buf) < 0)
return false;
if(setControlCommand(PL2303_REQTYPE_DEVICE2HOST_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x8383, 0, buf) < 0)
return false;
if(setControlCommand(PL2303_REQTYPE_HOST2DEVICE_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x0000, 1, null) < 0)
return false;
if(setControlCommand(PL2303_REQTYPE_HOST2DEVICE_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x0001, 0, null) < 0)
return false;
if(setControlCommand(PL2303_REQTYPE_HOST2DEVICE_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x0002, 0x0044, null) < 0)
return false;
// End of specific vendor stuff
setControlCommand(PL2303_REQTYPE_HOST2DEVICE, PL2303_SET_CONTROL_REQUEST, 0x0003, 0,null);
setControlCommand(PL2303_REQTYPE_HOST2DEVICE, PL2303_SET_LINE_CODING, 0x0000, 0, defaultSetLine);
setControlCommand(PL2303_REQTYPE_HOST2DEVICE_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x0505, 0x1311, null);
if(setControlCommand(PL2303_REQTYPE_HOST2DEVICE, PL2303_SET_CONTROL_REQUEST, 0x0003, 0,null) < 0)
return false;
if(setControlCommand(PL2303_REQTYPE_HOST2DEVICE, PL2303_SET_LINE_CODING, 0x0000, 0, defaultSetLine) < 0)
return false;
if(setControlCommand(PL2303_REQTYPE_HOST2DEVICE_VENDOR, PL2303_VENDOR_WRITE_REQUEST, 0x0505, 0x1311, null) < 0)
return false;
// Initialize UsbRequest
requestIN = new UsbRequest();
requestIN.initialize(connection, inEndpoint);
// Pass references to the threads
setThreadsParams(requestIN, outEndpoint);
return true;
}
@Override

Wyświetl plik

@ -56,6 +56,11 @@ public abstract class UsbSerialDevice implements UsbSerialInterface
public static UsbSerialDevice createUsbSerialDevice(UsbDevice device, UsbDeviceConnection connection)
{
/*
* It checks given vid and pid and will return a custom driver or a CDC serial driver.
* When CDC is returned open() method is even more important, its response will inform about if it can be really
* opened as a serial device with a generic CDC serial driver
*/
int vid = device.getVendorId();
int pid = device.getProductId();
if(FTDISioIds.isDeviceSupported(vid, pid))
@ -64,15 +69,13 @@ public abstract class UsbSerialDevice implements UsbSerialInterface
return new CP2102SerialDevice(device, connection);
else if(PL2303Ids.isDeviceSupported(vid, pid))
return new PL2303SerialDevice(device, connection);
else if(vid == 0x2458) // BLED112
return new BLED112SerialDevice(device, connection);
else
return null;
else
return new CDCSerialDevice(device, connection);
}
// Common Usb Serial Operations (I/O Asynchronous)
@Override
public abstract void open();
public abstract boolean open();
@Override
public void write(byte[] buffer)

Wyświetl plik

@ -29,7 +29,7 @@ public interface UsbSerialInterface
public static final int FLOW_CONTROL_XON_XOFF = 3;
// Common Usb Serial Operations (I/O Asynchronous)
public void open();
public boolean open();
public void write(byte[] buffer);
public int read(UsbReadCallback mCallback);
public void close();