public static final String TAG = "CH9326UARTDriver";
private UsbManager mUsbmanager;
private PendingIntent mPendingIntent;
private UsbDevice mUsbDevice;
private UsbInterface mInterface;
private UsbEndpoint mBulkInPoint;
private UsbEndpoint mBulkOutPoint;
private UsbDeviceConnection mDeviceConnection;
private Context mContext;
private String mString;
private boolean BroadcastFlag = false;
public boolean READ_ENABLE = false;
public read_thread readThread;
private Object WriteLock = new Object();
private Object ReadLock = new Object();
private byte[] readBuffer; /* circular buffer */
private byte[] usbdata;
private int writeIndex;
private int readIndex;
private int readcount;
private int totalBytes;
private int mBulkPacketSize;
final int maxnumbytes = 65536;
public int WriteTimeOutMillis;
public int ReadTimeOutMillis;
private int DEFAULT_TIMEOUT = 300;
public CH9326UARTDriver(UsbManager manager, Context context, String AppName) {
super();
readBuffer = new byte[maxnumbytes];
usbdata = new byte[1024];
writeIndex = 0;
readIndex = 0;
mUsbmanager = manager;
mContext = context;
mString = AppName;
WriteTimeOutMillis = 10000;
ReadTimeOutMillis = 10000;
}
/**
* 设置串口的读写超时
*
* @param WriteTimeOut
* 写超时(单位Ms)
* @param ReadTimeOut
* 读超时(单位Ms)
*/
public void SetTimeOut(int WriteTimeOut, int ReadTimeOut) {
WriteTimeOutMillis = WriteTimeOut;
ReadTimeOutMillis = ReadTimeOut;
}
private void OpenUsbDevice(UsbDevice mDevice) {
Object localObject;
UsbInterface intf;
if (mDevice == null)
return;
intf = getUsbInterface(mDevice);
if ((mDevice != null) && (intf != null)) {
localObject = this.mUsbmanager.openDevice(mDevice);
if (localObject != null) {
if (((UsbDeviceConnection) localObject).claimInterface(intf,
true)) {
this.mUsbDevice = mDevice;
this.mDeviceConnection = ((UsbDeviceConnection) localObject);
this.mInterface = intf;
enumerateEndPoint(intf);
if (READ_ENABLE == false) {
READ_ENABLE = true;
readThread = new read_thread(mBulkInPoint,
mDeviceConnection);
readThread.start();
}
return;
}
}
}
}
/**
* 打开CH9326设备
*
* @param mDevice
* 需要打开的CH9326设备
*/
public void OpenDevice(UsbDevice mDevice) {
mPendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(
mString), 0);
if (mUsbmanager.hasPermission(mDevice)) {
OpenUsbDevice(mDevice);
} else {
synchronized (mUsbReceiver) {
mUsbmanager.requestPermission(mDevice, mPendingIntent);
}
}
}
/**
* 关闭设备
*/
public synchronized void CloseDevice() {
if (this.mDeviceConnection != null) {
if (this.mInterface != null) {
this.mDeviceConnection.releaseInterface(this.mInterface);
this.mInterface = null;
}
this.mDeviceConnection.close();
}
if (this.mUsbDevice != null) {
this.mUsbDevice = null;
}
if (this.mUsbmanager != null) {
this.mUsbmanager = null;
}
if (READ_ENABLE == true) {
READ_ENABLE = false;
}
// 注销广播接收器
if (BroadcastFlag == true) {
this.mContext.unregisterReceiver(mUsbReceiver);
BroadcastFlag = false;
}
}
/**
* 判断系统是否支持USB HOST功能
*
* @return false:不支持USB HOST模式 ;true:支持UBS HOST模式
*/
public boolean UsbFeatureSupported() {
boolean bool = this.mContext.getPackageManager().hasSystemFeature(
"android.hardware.usb.host");
return bool;
}
/**
* 枚举并打开CH9326设备
*
* @return 0:表示打开失败; 1:表示打开成功
*/
public synchronized boolean ResumeUsbList() {
mUsbmanager = (UsbManager) mContext
.getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = mUsbmanager.getDeviceList();
if (deviceList.isEmpty()) {
Toast.makeText(mContext, "No Device Or Device Not Match",
Toast.LENGTH_LONG).show();
return false;
}
Iterator<UsbDevice> localIterator = deviceList.values().iterator();
while (localIterator.hasNext()) {
UsbDevice localUsbDevice = localIterator.next();
if (localUsbDevice.getVendorId() == 0x1a86
&& localUsbDevice.getProductId() == 0xe010) {
Log.d(TAG, "device found");
IntentFilter filter = new IntentFilter(mString);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
mContext.registerReceiver(mUsbReceiver, filter);
BroadcastFlag = true;
if (mUsbmanager.hasPermission(localUsbDevice)) {
OpenUsbDevice(localUsbDevice);
} else {
synchronized (mUsbReceiver) {
mUsbmanager.requestPermission(localUsbDevice,
mPendingIntent);
}
}
return true;
}
}
return false;
}
/**
* 枚举CH9326设备
*
* @return 返回枚举到的设备,如果没有设备则返回null
*/
public synchronized UsbDevice EnumerateDevice() {
mUsbmanager = (UsbManager) mContext
.getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = mUsbmanager.getDeviceList();
if (deviceList.isEmpty()) {
Toast.makeText(mContext, "No Device Or Device Not Match",
Toast.LENGTH_LONG).show();
return null;
}
Iterator<UsbDevice> localIterator = deviceList.values().iterator();
while (localIterator.hasNext()) {
UsbDevice localUsbDevice = localIterator.next();
if (localUsbDevice.getVendorId() == 0x1a86
&& localUsbDevice.getProductId() == 0xe010) {
Log.d(TAG, "device found");
IntentFilter filter = new IntentFilter(mString);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
mContext.registerReceiver(mUsbReceiver, filter);
BroadcastFlag = true;
return localUsbDevice;
}
}
return null;
}
/**
* 设备是否连接
*
* @return true:设备连接正常 ;false:设备未连接
*/
public boolean isConnected() {
return (this.mUsbDevice != null) && (this.mInterface != null)
&& (this.mDeviceConnection != null);
}
/**
* @return 获取到的CH9326设备
*/
protected UsbDevice getUsbDevice() {
return this.mUsbDevice;
}
/**
* 设置串口参数
*
* @param baudRate
* 01 = 300bps, 02 = 600bps, 03 = 1200bps, 04 = 2400bps, 05 =
* 4800bps, 06 = 9600(default)bps, 07 = 14400bps, 08 = 19200bps,
* 09 = 28800bps, 10 = 38400bps, 11 = 57600bps, 12 = 76800bps, 13
* = 115200bps
* @param dataBit
* 01 = 5bit data bit, 02 = 6bit data bit, 03 = 7bit data bit, 04
* = 8bit data bit(default)
* @param stopBit
* 01 = 1bit stop bit(default) ,02 = 2bit stop bit
* @param parity
* 01 = odd, 02 = even, 03 = space, 04 = none(default)
* @return true:设置成功 false:设置失败
*/
public synchronized boolean SetConfig(int baudRate, int dataBit,
int stopBit, int parity) {
byte interval = 0x10;
byte[] buf = new byte[32];
byte[] m_str = new byte[5];
int size, len;
if (baudRate < 1 || baudRate > 14 || parity < 1 || parity > 4
|| stopBit < 1 || stopBit > 2 || dataBit < 1 || dataBit > 4) {
return false;
}
if (baudRate == 1) // 300bps
{
m_str[2] = (byte) 0x80;
m_str[3] = (byte) 0xD9;
m_str[4] = interval;
m_str[0] |= 0x01;
} else if (baudRate == 2) // 600bps
{
m_str[2] = (byte) 0x81;
m_str[3] = 0x64;
m_str[4] = interval;
m_str[0] |= 0x01;
} else if (baudRate == 3) // 1200bps
{
m_str[2] = (byte) 0x81;
m_str[3] = (byte) 0xB2;
m_str[4] = interval;
m_str[0] |= 0x01;
} else if (baudRate == 4) // 2400bps
{
m_str[2] = (byte) 0x81;
m_str[3] = (byte) 0xD9;
m_str[4] = interval;
m_str[0] |= 0x01;
} else if (baudRate == 5) // 4800bps
{
m_str[2] = (byte) 0x82;
m_str[3] = 0x64;
m_str[4] = interval;
m_str[0] |= 0x01;
} else if (baudRate == 6) // 9600bps
{
m_str[2] = (byte) 0x82;
m_str[3] = (byte) 0xB2;
m_str[4] = interval;
m_str[0] |= 0x01;
} else if (baudRate == 7) // 14400bps
{
m_str[2] = (byte) 0x82;
m_str[3] = (byte) 0xCC;
m_str[4] = interval;
m_str[0] |= 0x01;
} else if (baudRate == 8) // 19200bps
{
m_str[2] = (byte) 0x82;
m_str[3] = (byte) 0xD9;
m_str[4] = interval;
m_str[0] |= 0x01;
} else if (baudRate == 9) // 28800bps
{
m_str[2] = (byte) 0x83;
m_str[3] = 0x30;
m_str[4] = interval;
m_str[0] |= 0x01;
} else if (baudRate == 10) // 38400bps
{
m_str[2] = (byte) 0x83;
m_str[3] = 0x64;
m_str[4] = interval;
m_str[0] |= 0x01;
} else if (baudRate == 11) // 57600
{
m_str[2] = (byte) 0x83;
m_str[3] = (byte) 0x98;
m_str[4] = interval;
m_str[0] |= 0x01;
} else if (baudRate == 12) // 76800
{
m_str[2] = (byte) 0x83;
m_str[3] = (byte) 0xB2;
m_str[4] = interval;
m_str[0] |= 0x01;
} else if (baudRate == 13) // 115200
{
m_str[2] = (byte) 0x83;
m_str[3] = (byte) 0xCC;
m_str[4] = interval;
m_str[0] |= 0x01;
}
if (parity == 1) // odd
{
m_str[1] &= ~0x30;
m_str[1] |= 0x08;
} else if (parity == 2) // even
{
m_str[1] &= ~0x10;
m_str[1] |= 0x18;
} else if (parity == 3) // space
{
m_str[1] |= 0x38;
} else if (parity == 4) // none
{
m_str[1] &= ~0x08;
}
if (stopBit == 1) // 1 bit
{
m_str[1] |= 0x04;
} else if (stopBit == 2) // 2 bit
{
m_str[1] &= ~0x04;
}
if (dataBit == 1) // 5 bit
{
m_str[1] &= ~0x3;
} else if (dataBit == 2) // 6 bit
{
m_str[1] &= ~0x3;
m_str[1] |= 0x1;
} else if (dataBit == 3) // 7 bit
{
m_str[1] &= ~0x3;
m_str[1] |= 0x2;
} else if (dataBit == 4) // 8 bit
{
m_str[1] |= 0x3;
}
m_str[0] = (byte) 0xFF;
m_str[1] |= 0xC0;
buf[0] = m_str[0];
buf[1] = m_str[1];
buf[2] = m_str[2];
buf[3] = m_str[3];
buf[4] = m_str[4];
size = 32;
len = mDeviceConnection.controlTransfer(UsbType.USB_TYPE_CLASS
| UsbType.USB_RECIP_DEVICE | UsbType.USB_DIR_OUT,
HID_Constants.HID_REPORT_SET, HID_Constants.HID_RT_OUTPUT << 8,
0x00, buf, size, DEFAULT_TIMEOUT);
if (len <= 0) {
return false;
} else {
Log.i(TAG, "control transfer len=" + len);
}
return true;
}
/**
* 串口读数据
*
* @param data
* 接收缓冲区
* @param length
* 需要读取的数据长度,每次读取的数据值不超过256
* @return 返回实际读取的数据长度
*/
public int ReadData(byte[] data, int length)
{
int mLen;
/* should be at least one byte to read */
if ((length < 1) || (totalBytes == 0)) {
mLen = 0;
return mLen;
}
if(length>256)
length=256;//这是为了防止取太多如果取了接近整个环形缓冲区的容量的数组,而此时CPU切换到硬件读数据的线程中去会将为读取的数据给覆盖了
/* check for max limit */
if (length > totalBytes)
length = totalBytes;
/* update the number of bytes available */
totalBytes -= length;//就在此时跳转到线程从usb硬件读取数据时,此时totalBytes为0,会将把此时为取走的数据给覆盖掉
mLen = length;
/* copy to the user buffer */
for (int count = 0; count < length; count++) {
data[count] = readBuffer[readIndex];
readIndex++;
/*
* shouldnt read more than what is there in the buffer, so no need
* to check the overflow
*/
readIndex %= maxnumbytes;
}
return mLen;
}
/**
* 串口写数据
*
* @param buf
* 实际需要写入的字节数组
* @param length
* 需要写入的字节长度
* @return 返回实际写入的字节长度
*/
public int WriteData(byte[] buf, int length) {
int mLen = 0;
mLen = WriteData(buf, length, this.WriteTimeOutMillis);
return mLen;
}
/**
* 串口写数据
*
* @param buf
* 需要发送的字符数组
* @param length
* 发送的数据长度
* @param timeoutMillis
* 发送超时
* @return 返回实际写出的数据长度
*/
public int WriteData(byte[] buf, int length, int timeoutMillis) {
int offset = 0;
int HasWritten = 0;
int old_len = length;
if (this.mBulkOutPoint == null)
return -1;
synchronized (WriteLock) {
while (offset < length) {
int mLen = Math.min(old_len, this.mBulkPacketSize - 1);
byte[] arrayOfByte = new byte[mLen + 1];
arrayOfByte[0] = (byte) mLen;
if (offset == 0) {
System.arraycopy(buf, 0, arrayOfByte, 1, mLen);
} else {
System.arraycopy(buf, offset, arrayOfByte, 1, mLen);
}
HasWritten = this.mDeviceConnection.bulkTransfer(
this.mBulkOutPoint, arrayOfByte, mLen + 1,
timeoutMillis);
HasWritten = HasWritten - 1;// 发送的数据长度为实际发送的值-1
if (HasWritten < 0) {
return -1;
} else {
offset += HasWritten;
old_len -= HasWritten;
}
}
}
return offset;
}
private void enumerateEndPoint(UsbInterface sInterface) {
if (sInterface == null)
return;
for (int i = 0; i < sInterface.getEndpointCount(); ++i) {
UsbEndpoint endPoint = sInterface.getEndpoint(i);
if (endPoint.getAddress() == 0x82
&& endPoint.getMaxPacketSize() == 0x20) {
mBulkInPoint = endPoint;
} else if (endPoint.getAddress() == 0x02) {
mBulkOutPoint = endPoint;
}
this.mBulkPacketSize = endPoint.getMaxPacketSize();
}
return;
}
private UsbInterface getUsbInterface(UsbDevice paramUsbDevice) {
if (this.mDeviceConnection != null) {
if (this.mInterface != null) {
this.mDeviceConnection.releaseInterface(this.mInterface);
this.mInterface = null;
}
this.mDeviceConnection.close();
this.mUsbDevice = null;
this.mInterface = null;
}
if (paramUsbDevice == null)
return null;
for (int i = 0; i < paramUsbDevice.getInterfaceCount(); i++) {
UsbInterface intf = paramUsbDevice.getInterface(i);
if (intf.getInterfaceClass() == 0x03
&& intf.getInterfaceSubclass() == 0x00) {
return intf;
}
}
return null;
}
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action))
return;
if (mString.equals(action)) {
synchronized (ReadLock) {
UsbDevice localUsbDevice = (UsbDevice) intent
.getParcelableExtra("device");
if (intent.getBooleanExtra(
UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
OpenUsbDevice(localUsbDevice);
} else {
Toast.makeText(CH9326UARTDriver.this.mContext,
"Deny USB Permission", Toast.LENGTH_SHORT)
.show();
Log.d(TAG, "permission denied");
}
}
} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
Toast.makeText(CH9326UARTDriver.this.mContext, "Disconnect",
Toast.LENGTH_SHORT).show();
CloseDevice();
} else {
Log.d(TAG, "......");
}
}
};
/**
* 内部的接收数据的线程,将接受到的数据存放在环形缓冲区内
*/
private class read_thread extends Thread {
UsbEndpoint endpoint;
UsbDeviceConnection mConn;
read_thread(UsbEndpoint point, UsbDeviceConnection con) {
endpoint = point;
mConn = con;
this.setPriority(Thread.MAX_PRIORITY);
}
public void run() {
while (READ_ENABLE == true) {
synchronized (ReadLock) {
while (totalBytes > (maxnumbytes - 256)) {//防止接收过快的时候会覆盖缓冲区
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (endpoint != null) {
readcount = mConn.bulkTransfer(endpoint, usbdata, 32,
ReadTimeOutMillis);
if (readcount > 0) {
readcount = usbdata[0];// 读到的数据的第一个字节为接收到的数据长度,数组以后的部分才是实际读取到的数据
for (int count = 1; count <= readcount; count++) {
readBuffer[writeIndex] = usbdata[count];
writeIndex++;
writeIndex %= maxnumbytes;
}
if (writeIndex >= readIndex)
totalBytes = writeIndex - readIndex;
else
totalBytes = (maxnumbytes - readIndex)
+ writeIndex;
}
}
}
}
}
}
private final class UsbType {
public static final int USB_TYPE_CLASS = 0x20;
public static final int USB_RECIP_DEVICE = 0x00;
public static final int USB_DIR_OUT = 0x00;
public static final int USB_DIR_IN = 0x80;
}
private final class HID_Constants {
public static final int HID_RT_INPUT = 0x01;
public static final int HID_RT_OUTPUT = 0x02;
public static final int HID_REPORT_GET = 0x01;
public static final int HID_REPORT_SET = 0x09;
}