最近做了个平板与单片机的项目,由于使用的平板不支持串口,所以中间借助了usb-串口转换器(PL2303)。
这方面的资料可以说少之又少,几乎没有,我唯一能找到的就是usb-serial-for-android,一个国外的开源项目。
实现了一些主要的转换器的驱动,但是国内一般用得最多的还是PL2303。
我将usb-serial-for-android的驱动简化了下,成功的与串口调试工具通信了,能读,能写。给大家分享下。
或者直接下载
驱动源码:packagecom.example.android_usb;
importjava.io.ByteArrayOutputStream;
importjava.io.IOException;
importjava.lang.reflect.Method;
importandroid.app.PendingIntent;
importandroid.content.Context;
importandroid.content.Intent;
importandroid.hardware.usb.UsbConstants;
importandroid.hardware.usb.UsbDevice;
importandroid.hardware.usb.UsbDeviceConnection;
importandroid.hardware.usb.UsbEndpoint;
importandroid.hardware.usb.UsbInterface;
importandroid.hardware.usb.UsbManager;
importandroid.util.Log;
importandroid.widget.Toast;
/**
*PL2303串口驱动
*@authorpc
*
*/
publicclassProlificSerialDriver{
privatestaticfinalintUSB_READ_TIMEOUT_MILLIS=5000;
privatestaticfinalintUSB_WRITE_TIMEOUT_MILLIS=3000;
privatefinalObjectmReadBufferLock=newObject();
privatefinalObjectmWriteBufferLock=newObject();
privatebyte[]buffer=newbyte[4096];
privateByteArrayOutputStreambufferOS=newByteArrayOutputStream();
privateContextcontext;
privateUsbEndpointmReadEndpoint;
privateUsbEndpointmWriteEndpoint;
privateUsbDeviceConnectionconnection;
privateUsbDeviceusbDevice;
publicProlificSerialDriver(Contextcontext,UsbDeviceusbDevice){
this.context=context;
this.usbDevice=usbDevice;
}
/**
*安装
*@parambaudRate
*@throwsIOException
*/
publicvoidsetup(intbaudRate)throwsIOException{
open();
initPL2303Chip();
ctrlOut(baudRate);
}
privatevoidopen()throwsIOException{
UsbManagerusbManager=(UsbManager)context.getSystemService(Context.USB_SERVICE);
//申请权限
PendingIntentmPermissionIntent=PendingIntent.getBroadcast(context,0,newIntent("com.prolific.pl2303hxdsimpletest.USB_PERMISSION"),0);
usbManager.requestPermission(usbDevice,mPermissionIntent);
UsbInterfaceusbInterface=usbDevice.getInterface(0);
for(inti=0;i
UsbEndpointcurrentEndpoint=usbInterface.getEndpoint(i);
switch(currentEndpoint.getAddress()){
case0x83:
mReadEndpoint=currentEndpoint;
break;
case0x02:
mWriteEndpoint=currentEndpoint;
break;
}
}
connection=usbManager.openDevice(usbDevice);
connection.claimInterface(usbInterface,true);
}
privatefinalvoidctrlOut(intbaudRate)throwsIOException{
//设置传输控制
byte[]lineRequestData=newbyte[7];
lineRequestData[0]=(byte)(baudRate&0xff);
lineRequestData[1]=(byte)((baudRate>>8)&0xff);
lineRequestData[2]=(byte)((baudRate>>16)&0xff);
lineRequestData[3]=(byte)((baudRate>>24)&0xff);
lineRequestData[4]=0;
lineRequestData[5]=0;
lineRequestData[6]=(byte)8;
outControlTransfer(UsbConstants.USB_DIR_OUT|UsbConstants.USB_TYPE_CLASS|0x01,0x20,0,0,lineRequestData);
}
/**
*初始化芯片
*@throwsIOException
*/
privatevoidinitPL2303Chip()throwsIOException{
intmDeviceType=getDeviceType();
vendorIn(0x8484,0,1);
vendorOut(0x0404,0,null);
vendorIn(0x8484,0,1);
vendorIn(0x8383,0,1);
vendorIn(0x8484,0,1);
vendorOut(0x0404,1,null);
vendorIn(0x8484,0,1);
vendorIn(0x8383,0,1);
vendorOut(0,1,null);
vendorOut(1,0,null);
vendorOut(2,(mDeviceType==0)?0x44:0x24,null);
}
/**
*获得设备类型
*/
privateintgetDeviceType(){
intmDeviceType=0;
try{
if(usbDevice.getDeviceClass()==0x02){
mDeviceType=1;
}else{
MethodgetRawDescriptorsMethod=connection.getClass().getMethod("getRawDescriptors");
byte[]rawDescriptors=(byte[])getRawDescriptorsMethod.invoke(connection);
bytemaxPacketSize0=rawDescriptors[7];
if(maxPacketSize0==64){
mDeviceType=0;
}elseif((usbDevice.getDeviceClass()==0x00)||(usbDevice.getDeviceClass()==0xff)){
mDeviceType=2;
}else{
mDeviceType=0;
}
}
}catch(Exceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
returnmDeviceType;
}
/**
*写
*@parambuf
*@paramwlength
*@return
*/
publicintwrite(byte[]buf,intwlength){
intoffset=0;
byte[]write_buf=newbyte[4096];
synchronized(mWriteBufferLock){
while(offset
intwrite_size=4096;
if(offset+write_size>wlength){
write_size=wlength-offset;
}
System.arraycopy(buf,offset,write_buf,0,write_size);
intactual_length=this.connection.bulkTransfer(this.mWriteEndpoint,write_buf,write_size,USB_WRITE_TIMEOUT_MILLIS);
if(actual_length
return-1;
}
offset+=actual_length;
}
}
returnoffset;
}
/**
*读取
*@paramtimeoutMillis
*@throwsIOException
*/
publicbyte[]read()throwsIOException{
synchronized(mReadBufferLock){
try{
bufferOS.reset();
intnumber=0;
while(number!=-1){
number=connection.bulkTransfer(mReadEndpoint,buffer,buffer.length,USB_READ_TIMEOUT_MILLIS);
MainActivity.showMessage("number:"+number);
bufferOS.write(buffer,0,number);
}
}catch(Exceptione){
e.printStackTrace();
}
}
returnbufferOS.toByteArray();
}
/**
*关闭资源
*/
publicvoidclose(){
try{
if(connection==null){
return;
}
connection.releaseInterface(this.usbDevice.getInterface(0));
}catch(Exceptione){
e.printStackTrace();
}
}
/**
*输出的传输
*@throwsIOException
*/
privatefinalvoidoutControlTransfer(intrequestType,intrequest,intvalue,intindex,byte[]data)throwsIOException{
intlength=(data==null)?0:data.length;
intresult=connection.controlTransfer(requestType,request,value,index,data,length,USB_WRITE_TIMEOUT_MILLIS);
if(result!=length){
thrownewIOException(String.format("ControlTransferwithvalue0x%xfailed:%d",value,result));
}
}
/**
*输入的传输
*@throwsIOException
*/
privatefinalbyte[]inControlTransfer(intrequestType,intrequest,intvalue,intindex,intlength)throwsIOException{
byte[]buffer=newbyte[length];
intresult=connection.controlTransfer(requestType,request,value,index,buffer,length,USB_READ_TIMEOUT_MILLIS);
if(result!=length){
thrownewIOException(String.format("ControlTransferwithvalue0x%xfailed:%d",value,result));
}
returnbuffer;
}
/**
*写设备控制
*/
privatefinalbyte[]vendorIn(intvalue,intindex,intlength)throwsIOException{
returninControlTransfer(UsbConstants.USB_DIR_IN|UsbConstants.USB_TYPE_VENDOR,0x01,value,index,length);
}
/**
*读设备控制
*/
privatefinalvoidvendorOut(intvalue,intindex,byte[]data)throwsIOException{
outControlTransfer(UsbConstants.USB_DIR_OUT|UsbConstants.USB_TYPE_VENDOR,0x01,value,index,data);
}
}