Merge pull request #26 from felHR85/flowcontrol_signals

Flow control signals
pull/30/head
Felipe Herranz 2016-02-13 13:19:02 +01:00
commit 16af699e11
11 zmienionych plików z 348 dodań i 17 usunięć

Wyświetl plik

@ -145,6 +145,12 @@ public class MainActivity extends AppCompatActivity {
String data = (String) msg.obj;
mActivity.get().display.append(data);
break;
case UsbService.CTS_CHANGE:
Toast.makeText(mActivity.get(), "CTS_CHANGE",Toast.LENGTH_LONG).show();
break;
case UsbService.DSR_CHANGE:
Toast.makeText(mActivity.get(), "DSR_CHANGE",Toast.LENGTH_LONG).show();
break;
}
}
}

Wyświetl plik

@ -34,6 +34,8 @@ public class UsbService extends Service {
public static final String ACTION_CDC_DRIVER_NOT_WORKING = "com.felhr.connectivityservices.ACTION_CDC_DRIVER_NOT_WORKING";
public static final String ACTION_USB_DEVICE_NOT_WORKING = "com.felhr.connectivityservices.ACTION_USB_DEVICE_NOT_WORKING";
public static final int MESSAGE_FROM_SERIAL_PORT = 0;
public static final int CTS_CHANGE = 1;
public static final int DSR_CHANGE = 2;
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
private static final int BAUD_RATE = 9600; // BaudRate. Change this value if you need
public static boolean SERVICE_CONNECTED = false;
@ -65,6 +67,28 @@ public class UsbService extends Service {
}
}
};
/*
* State changes in the CTS line will be received here
*/
private UsbSerialInterface.UsbCTSCallback ctsCallback = new UsbSerialInterface.UsbCTSCallback() {
@Override
public void onCTSChanged(boolean state) {
if(mHandler != null)
mHandler.obtainMessage(CTS_CHANGE).sendToTarget();
}
};
/*
* State chanteges in the DSR line will be received here
*/
private UsbSerialInterface.UsbDSRCallback dsrCallback = new UsbSerialInterface.UsbDSRCallback() {
@Override
public void onDSRChanged(boolean state) {
if(mHandler != null)
mHandler.obtainMessage(DSR_CHANGE).sendToTarget();
}
};
/*
* Different notifications from OS will be received here (USB attached, detached, permission responses...)
* About BroadcastReceiver: http://developer.android.com/reference/android/content/BroadcastReceiver.html
@ -215,9 +239,16 @@ public class UsbService extends Service {
serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8);
serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1);
serialPort.setParity(UsbSerialInterface.PARITY_NONE);
/**
* Current flow control Options:
* UsbSerialInterface.FLOW_CONTROL_OFF
* UsbSerialInterface.FLOW_CONTROL_RTS_CTS only for CP2102 and FT232
* UsbSerialInterface.FLOW_CONTROL_DSR_DTR only for CP2102 and FT232
*/
serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
serialPort.read(mCallback);
serialPort.getCTS(ctsCallback);
serialPort.getDSR(dsrCallback);
// Everything went as expected. Send an intent to MainActivity
Intent intent = new Intent(ACTION_USB_READY);
context.sendBroadcast(intent);

Wyświetl plik

@ -223,6 +223,30 @@ public class BLED112SerialDevice extends UsbSerialDevice
//TODO
}
@Override
public void getBreak(UsbBreakCallback breakCallback)
{
//TODO
}
@Override
public void getFrame(UsbFrameCallback frameCallback)
{
//TODO
}
@Override
public void getOverrun(UsbOverrunCallback overrunCallback)
{
//TODO
}
@Override
public void getParity(UsbParityCallback parityCallback)
{
//TODO
}
private int setControlCommand(int request, int value, byte[] data)
{
int dataLength = 0;

Wyświetl plik

@ -239,6 +239,30 @@ public class CDCSerialDevice extends UsbSerialDevice
//TODO
}
@Override
public void getBreak(UsbBreakCallback breakCallback)
{
//TODO
}
@Override
public void getFrame(UsbFrameCallback frameCallback)
{
//TODO
}
@Override
public void getOverrun(UsbOverrunCallback overrunCallback)
{
//TODO
}
@Override
public void getParity(UsbParityCallback parityCallback)
{
//TODO
}
private int setControlCommand(int request, int value, byte[] data)
{
int dataLength = 0;

Wyświetl plik

@ -267,6 +267,30 @@ public class CH34xSerialDevice extends UsbSerialDevice
//TODO
}
@Override
public void getBreak(UsbBreakCallback breakCallback)
{
//TODO
}
@Override
public void getFrame(UsbFrameCallback frameCallback)
{
//TODO
}
@Override
public void getOverrun(UsbOverrunCallback overrunCallback)
{
//TODO
}
@Override
public void getParity(UsbParityCallback parityCallback)
{
//TODO
}
private int init()
{
if(checkState("init #1", 0x5f, 0, new int[]{-1 /* 0x27, 0x30 */, 0x00}) == -1)

Wyświetl plik

@ -270,6 +270,8 @@ public class CP2102SerialDevice extends UsbSerialDevice
(byte) 0x00, (byte) 0x80, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x20, (byte) 0x00, (byte) 0x00
};
rtsCtsEnabled = false;
dtrDsrEnabled = false;
setControlCommand(CP210x_SET_FLOW, 0, dataOff);
break;
case UsbSerialInterface.FLOW_CONTROL_RTS_CTS:
@ -280,6 +282,7 @@ public class CP2102SerialDevice extends UsbSerialDevice
(byte) 0x00, (byte) 0x20, (byte) 0x00, (byte) 0x00
};
rtsCtsEnabled = true;
dtrDsrEnabled = false;
setControlCommand(CP210x_SET_FLOW, 0, dataRTSCTS);
setControlCommand(CP210x_SET_MHS, CP210x_MHS_RTS_ON, null);
byte[] commStatusCTS = getCommStatus();
@ -294,6 +297,7 @@ public class CP2102SerialDevice extends UsbSerialDevice
(byte) 0x00, (byte) 0x20, (byte) 0x00, (byte) 0x00
};
dtrDsrEnabled = true;
rtsCtsEnabled = false;
setControlCommand(CP210x_SET_FLOW, 0, dataDSRDTR);
setControlCommand(CP210x_SET_MHS, CP210x_MHS_DTR_ON, null);
byte[] commStatusDSR = getCommStatus();
@ -356,9 +360,33 @@ public class CP2102SerialDevice extends UsbSerialDevice
this.dsrCallback = dsrCallback;
}
@Override
public void getBreak(UsbBreakCallback breakCallback)
{
//TODO
}
@Override
public void getFrame(UsbFrameCallback frameCallback)
{
//TODO
}
@Override
public void getOverrun(UsbOverrunCallback overrunCallback)
{
//TODO
}
@Override
public void getParity(UsbParityCallback parityCallback)
{
//TODO
}
/*
Thread to check every X time if flow signals CTS or DSR have been raised
*/
Thread to check every X time if flow signals CTS or DSR have been raised
*/
private class FlowControlThread extends Thread
{
private long time = 40; // 40ms

Wyświetl plik

@ -22,6 +22,17 @@ public class FTDISerialDevice extends UsbSerialDevice
private static final int FTDI_REQTYPE_HOST2DEVICE = 0x40;
/**
* RTS and DTR values obtained from FreeBSD FTDI driver
* https://github.com/freebsd/freebsd/blob/70b396ca9c54a94c3fad73c3ceb0a76dffbde635/sys/dev/usb/serial/uftdi_reg.h
*/
private static final int FTDI_SIO_SET_DTR_MASK = 0x1;
private static final int FTDI_SIO_SET_DTR_HIGH = (1 | (FTDI_SIO_SET_DTR_MASK << 8));
private static final int FTDI_SIO_SET_DTR_LOW = (0 | (FTDI_SIO_SET_DTR_MASK << 8));
private static final int FTDI_SIO_SET_RTS_MASK = 0x2;
private static final int FTDI_SIO_SET_RTS_HIGH = (2 | (FTDI_SIO_SET_RTS_MASK << 8));
private static final int FTDI_SIO_SET_RTS_LOW = (0 | (FTDI_SIO_SET_RTS_MASK << 8));
public static final int FTDI_BAUDRATE_300 = 0x2710;
public static final int FTDI_BAUDRATE_600 = 0x1388;
public static final int FTDI_BAUDRATE_1200 = 0x09c4;
@ -53,11 +64,26 @@ public class FTDISerialDevice extends UsbSerialDevice
private int currentSioSetData = 0x0000;
/**
* Flow control variables
*/
private boolean rtsCtsEnabled;
private boolean dtrDsrEnabled;
private boolean ctsState;
private boolean dsrState;
private boolean firstTime; // with this flag we set the CTS and DSR state to the first value received from the FTDI device
private UsbCTSCallback ctsCallback;
private UsbDSRCallback dsrCallback;
private UsbInterface mInterface;
private UsbEndpoint inEndpoint;
private UsbEndpoint outEndpoint;
private UsbRequest requestIN;
public FTDIUtilities ftdiUtilities;
public FTDISerialDevice(UsbDevice device, UsbDeviceConnection connection)
{
@ -67,6 +93,12 @@ public class FTDISerialDevice extends UsbSerialDevice
public FTDISerialDevice(UsbDevice device, UsbDeviceConnection connection, int iface)
{
super(device, connection);
ftdiUtilities = new FTDIUtilities();
rtsCtsEnabled = false;
dtrDsrEnabled = false;
ctsState = true;
dsrState = true;
firstTime = true;
mInterface = device.getInterface(iface >= 0 ? iface : 0);
}
@ -98,6 +130,7 @@ public class FTDISerialDevice extends UsbSerialDevice
}
// Default Setup
firstTime = true;
if(setControlCommand(FTDI_SIO_RESET, 0x00, 0, null) < 0)
return false;
if(setControlCommand(FTDI_SIO_SET_DATA, FTDI_SET_DATA_DEFAULT, 0, null) < 0)
@ -112,6 +145,10 @@ public class FTDISerialDevice extends UsbSerialDevice
if(setControlCommand(FTDI_SIO_SET_BAUD_RATE, FTDI_BAUDRATE_9600, 0, null) < 0)
return false;
// Flow control disabled by default
rtsCtsEnabled = false;
dtrDsrEnabled = false;
// Initialize UsbRequest
requestIN = new UsbRequest();
requestIN.initialize(connection, inEndpoint);
@ -302,12 +339,18 @@ public class FTDISerialDevice extends UsbSerialDevice
{
case UsbSerialInterface.FLOW_CONTROL_OFF:
setControlCommand(FTDI_SIO_SET_FLOW_CTRL, FTDI_SET_FLOW_CTRL_DEFAULT, 0, null);
rtsCtsEnabled = false;
dtrDsrEnabled = false;
break;
case UsbSerialInterface.FLOW_CONTROL_RTS_CTS:
rtsCtsEnabled = true;
dtrDsrEnabled = false;
int indexRTSCTS = 0x0001;
setControlCommand(FTDI_SIO_SET_FLOW_CTRL, FTDI_SET_FLOW_CTRL_DEFAULT, indexRTSCTS, null);
break;
case UsbSerialInterface.FLOW_CONTROL_DSR_DTR:
dtrDsrEnabled = true;
rtsCtsEnabled = false;
int indexDSRDTR = 0x0002;
setControlCommand(FTDI_SIO_SET_FLOW_CTRL, FTDI_SET_FLOW_CTRL_DEFAULT, indexDSRDTR , null);
break;
@ -325,23 +368,59 @@ public class FTDISerialDevice extends UsbSerialDevice
@Override
public void setRTS(boolean state)
{
//TODO
if(state)
{
setControlCommand(FTDI_SIO_MODEM_CTRL, FTDI_SIO_SET_RTS_HIGH, 0, null);
}else
{
setControlCommand(FTDI_SIO_MODEM_CTRL, FTDI_SIO_SET_RTS_LOW, 0, null);
}
}
@Override
public void setDTR(boolean state)
{
//TODO
if(state)
{
setControlCommand(FTDI_SIO_MODEM_CTRL, FTDI_SIO_SET_DTR_HIGH, 0, null);
}else
{
setControlCommand(FTDI_SIO_MODEM_CTRL, FTDI_SIO_SET_DTR_LOW, 0, null);
}
}
@Override
public void getCTS(UsbCTSCallback ctsCallback)
{
//TODO
this.ctsCallback = ctsCallback;
}
@Override
public void getDSR(UsbDSRCallback dsrCallback)
{
this.dsrCallback = dsrCallback;
}
@Override
public void getBreak(UsbBreakCallback breakCallback)
{
//TODO
}
@Override
public void getFrame(UsbFrameCallback frameCallback)
{
//TODO
}
@Override
public void getOverrun(UsbOverrunCallback overrunCallback)
{
//TODO
}
@Override
public void getParity(UsbParityCallback parityCallback)
{
//TODO
}
@ -358,10 +437,10 @@ public class FTDISerialDevice extends UsbSerialDevice
return response;
}
public static class FTDIUtilities
public class FTDIUtilities
{
// Special treatment needed to FTDI devices
public static byte[] adaptArray(byte[] ftdiData)
public byte[] adaptArray(byte[] ftdiData)
{
int length = ftdiData.length;
if(length > 64)
@ -384,8 +463,39 @@ public class FTDISerialDevice extends UsbSerialDevice
}
}
public void checkModemStatus(byte[] data)
{
if(data.length == 0) // Safeguard for zero length arrays
return;
boolean cts = (data[0] & 0x10) == 0x10;
boolean dsr = (data[0] & 0x20) == 0x20;
if(firstTime) // First modem status received, set the flags and exit
{
ctsState = cts;
dsrState = dsr;
firstTime = false;
return;
}
if(rtsCtsEnabled &&
cts != ctsState && ctsCallback != null) //CTS
{
ctsState = !ctsState;
ctsCallback.onCTSChanged(ctsState);
}
if(dtrDsrEnabled &&
dsr != dsrState && dsrCallback != null) //DSR
{
dsrState = !dsrState;
dsrCallback.onDSRChanged(dsrState);
}
}
// Copy data without FTDI headers
private static void copyData(byte[] src, byte[] dst)
private void copyData(byte[] src, byte[] dst)
{
int i = 0; // src index
int j = 0; // dst index

Wyświetl plik

@ -304,6 +304,30 @@ public class PL2303SerialDevice extends UsbSerialDevice
//TODO
}
@Override
public void getBreak(UsbBreakCallback breakCallback)
{
//TODO
}
@Override
public void getFrame(UsbFrameCallback frameCallback)
{
//TODO
}
@Override
public void getOverrun(UsbOverrunCallback overrunCallback)
{
//TODO
}
@Override
public void getParity(UsbParityCallback parityCallback)
{
//TODO
}
private int setControlCommand(int reqType , int request, int value, int index, byte[] data)
{
int dataLength = 0;

Wyświetl plik

@ -146,12 +146,15 @@ public abstract class UsbSerialDevice implements UsbSerialInterface
*/
protected class WorkerThread extends Thread
{
private UsbSerialDevice usbSerialDevice;
private UsbReadCallback callback;
private UsbRequest requestIN;
private AtomicBoolean working;
public WorkerThread()
public WorkerThread(UsbSerialDevice usbSerialDevice)
{
this.usbSerialDevice = usbSerialDevice;
working = new AtomicBoolean(true);
}
@ -170,11 +173,12 @@ public abstract class UsbSerialDevice implements UsbSerialInterface
// modem and Line.
if(isFTDIDevice())
{
((FTDISerialDevice) usbSerialDevice).ftdiUtilities.checkModemStatus(data); //Check the Modem status
serialBuffer.clearReadBuffer();
if(data.length > 2)
{
data = FTDISerialDevice.FTDIUtilities.adaptArray(data);
// Clear buffer, execute the callback
serialBuffer.clearReadBuffer();
data = ((FTDISerialDevice) usbSerialDevice).ftdiUtilities.adaptArray(data);
onReceivedData(data);
}
}else
@ -249,12 +253,15 @@ public abstract class UsbSerialDevice implements UsbSerialInterface
protected class ReadThread extends Thread
{
private UsbSerialDevice usbSerialDevice;
private UsbReadCallback callback;
private UsbEndpoint inEndpoint;
private AtomicBoolean working;
public ReadThread()
public ReadThread(UsbSerialDevice usbSerialDevice)
{
this.usbSerialDevice = usbSerialDevice;
working = new AtomicBoolean(true);
}
@ -285,9 +292,11 @@ public abstract class UsbSerialDevice implements UsbSerialInterface
// modem and Line.
if(isFTDIDevice())
{
((FTDISerialDevice) usbSerialDevice).ftdiUtilities.checkModemStatus(dataReceived);
if(dataReceived.length > 2)
{
dataReceived = FTDISerialDevice.FTDIUtilities.adaptArray(dataReceived);
dataReceived = ((FTDISerialDevice) usbSerialDevice).ftdiUtilities.adaptArray(dataReceived);
onReceivedData(dataReceived);
}
}else
@ -351,12 +360,12 @@ public abstract class UsbSerialDevice implements UsbSerialInterface
{
if(mr1Version && workerThread == null)
{
workerThread = new WorkerThread();
workerThread = new WorkerThread(this);
workerThread.start();
while(!workerThread.isAlive()){} // Busy waiting
}else if(!mr1Version && readThread == null)
{
readThread = new ReadThread();
readThread = new ReadThread(this);
readThread.start();
while(!readThread.isAlive()){} // Busy waiting
}

Wyświetl plik

@ -47,6 +47,12 @@ public interface UsbSerialInterface
void getCTS(UsbCTSCallback ctsCallback);
void getDSR(UsbDSRCallback dsrCallback);
// Status methods
void getBreak(UsbBreakCallback breakCallback);
void getFrame(UsbFrameCallback frameCallback);
void getOverrun(UsbOverrunCallback overrunCallback);
void getParity(UsbParityCallback parityCallback);
interface UsbCTSCallback
{
void onCTSChanged(boolean state);
@ -57,6 +63,27 @@ public interface UsbSerialInterface
void onDSRChanged(boolean state);
}
// Error signals callbacks
interface UsbBreakCallback
{
void onBreakInterrupt();
}
interface UsbFrameCallback
{
void onFramingError();
}
interface UsbOverrunCallback
{
void onOverrunError();
}
interface UsbParityCallback
{
void onParityError();
}
// Usb Read Callback
interface UsbReadCallback
{

Wyświetl plik

@ -310,6 +310,30 @@ public class XdcVcpSerialDevice extends UsbSerialDevice
//TODO
}
@Override
public void getBreak(UsbBreakCallback breakCallback)
{
//TODO
}
@Override
public void getFrame(UsbFrameCallback frameCallback)
{
//TODO
}
@Override
public void getOverrun(UsbOverrunCallback overrunCallback)
{
//TODO
}
@Override
public void getParity(UsbParityCallback parityCallback)
{
//TODO
}
private int setControlCommand(int request, int value, byte[] data)
{
int dataLength = 0;