mirror of
https://github.com/mik3y/usb-serial-for-android.git
synced 2026-10-15 15:40:55 +00:00
CH34x flow control
the tests look like the CH34x only partially supports flow control CTS ok: writing data correctly blocks if CTS is unset. RTS not ok: when not reading data (fast enough), RTS is not unset on buffer full
This commit is contained in:
@@ -54,7 +54,7 @@ project.afterEvaluate {
|
|||||||
// values used for local maven repo, jitpack uses github release:
|
// values used for local maven repo, jitpack uses github release:
|
||||||
groupId 'com.github.mik3y'
|
groupId 'com.github.mik3y'
|
||||||
artifactId 'usb-serial-for-android'
|
artifactId 'usb-serial-for-android'
|
||||||
version '3.9.1beta'
|
version '3.12.0beta'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-17
@@ -2185,6 +2185,7 @@ public class DeviceTest {
|
|||||||
boolean outputLineReadable = false; // getControlLines returns configured value
|
boolean outputLineReadable = false; // getControlLines returns configured value
|
||||||
FlowControl_OutputLineLocked outputLineLocked = FlowControl_OutputLineLocked.FALSE;
|
FlowControl_OutputLineLocked outputLineLocked = FlowControl_OutputLineLocked.FALSE;
|
||||||
boolean outputLineSet = false;
|
boolean outputLineSet = false;
|
||||||
|
boolean inputFlowControl = true;
|
||||||
if(usb.serialDriver instanceof ProlificSerialDriver) {
|
if(usb.serialDriver instanceof ProlificSerialDriver) {
|
||||||
outputLineSet = true; // line set to 'true' on setFlowControl
|
outputLineSet = true; // line set to 'true' on setFlowControl
|
||||||
outputLineLocked = FlowControl_OutputLineLocked.TRUE; // setRts/Dtr has no effect
|
outputLineLocked = FlowControl_OutputLineLocked.TRUE; // setRts/Dtr has no effect
|
||||||
@@ -2197,7 +2198,9 @@ public class DeviceTest {
|
|||||||
if(usb.serialDriver instanceof FtdiSerialDriver) {
|
if(usb.serialDriver instanceof FtdiSerialDriver) {
|
||||||
outputLineLocked = FlowControl_OutputLineLocked.ON_BUFFER_FULL;
|
outputLineLocked = FlowControl_OutputLineLocked.ON_BUFFER_FULL;
|
||||||
}
|
}
|
||||||
|
if(usb.serialDriver instanceof Ch34xSerialDriver) {
|
||||||
|
inputFlowControl = false;
|
||||||
|
}
|
||||||
usb.open(EnumSet.of(UsbWrapper.OpenCloseFlags.NO_CONTROL_LINE_INIT, UsbWrapper.OpenCloseFlags.NO_IOMANAGER_THREAD));
|
usb.open(EnumSet.of(UsbWrapper.OpenCloseFlags.NO_CONTROL_LINE_INIT, UsbWrapper.OpenCloseFlags.NO_IOMANAGER_THREAD));
|
||||||
telnet.setParameters(115200, 8, 1, UsbSerialPort.PARITY_NONE);
|
telnet.setParameters(115200, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||||
usb.setParameters(115200, 8, 1, UsbSerialPort.PARITY_NONE);
|
usb.setParameters(115200, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||||
@@ -2313,23 +2316,25 @@ public class DeviceTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
new NoRead().run();
|
if (inputFlowControl) {
|
||||||
|
new NoRead().run();
|
||||||
|
|
||||||
// no read -> buffer full -> RTS/DTR off -> output line locked
|
// no read -> buffer full -> RTS/DTR off -> output line locked
|
||||||
if(outputLineLocked != FlowControl_OutputLineLocked.TRUE) {
|
if (outputLineLocked != FlowControl_OutputLineLocked.TRUE) {
|
||||||
assertTrue(usb.serialPort.getControlLines().contains(m ? ControlLine.CTS : ControlLine.DSR));
|
|
||||||
for(i = 0; i < 120 && usb.serialPort.getControlLines().contains(m ? ControlLine.CTS : ControlLine.DSR); i++) {
|
|
||||||
telnet.write(buf64);
|
|
||||||
Thread.sleep(controlLineWait);
|
|
||||||
}
|
|
||||||
assertFalse(usb.serialPort.getControlLines().contains(m ? ControlLine.CTS : ControlLine.DSR));
|
|
||||||
if(m) usb.serialPort.setRTS(true); else usb.serialPort.setDTR(true);
|
|
||||||
Thread.sleep(controlLineWait);
|
|
||||||
if(outputLineLocked == FlowControl_OutputLineLocked.ON_BUFFER_FULL)
|
|
||||||
assertFalse(usb.serialPort.getControlLines().contains(m ? ControlLine.CTS : ControlLine.DSR));
|
|
||||||
else
|
|
||||||
assertTrue(usb.serialPort.getControlLines().contains(m ? ControlLine.CTS : ControlLine.DSR));
|
assertTrue(usb.serialPort.getControlLines().contains(m ? ControlLine.CTS : ControlLine.DSR));
|
||||||
data = usb.read(-1, i*64, 100);
|
for (i = 0; i < 120 && usb.serialPort.getControlLines().contains(m ? ControlLine.CTS : ControlLine.DSR); i++) {
|
||||||
|
telnet.write(buf64);
|
||||||
|
Thread.sleep(controlLineWait);
|
||||||
|
}
|
||||||
|
assertFalse(usb.serialPort.getControlLines().contains(m ? ControlLine.CTS : ControlLine.DSR)); // RTS not unset on CH34x
|
||||||
|
if (m) usb.serialPort.setRTS(true); else usb.serialPort.setDTR(true);
|
||||||
|
Thread.sleep(controlLineWait);
|
||||||
|
if (outputLineLocked == FlowControl_OutputLineLocked.ON_BUFFER_FULL)
|
||||||
|
assertFalse(usb.serialPort.getControlLines().contains(m ? ControlLine.CTS : ControlLine.DSR));
|
||||||
|
else
|
||||||
|
assertTrue(usb.serialPort.getControlLines().contains(m ? ControlLine.CTS : ControlLine.DSR));
|
||||||
|
data = usb.read(-1, i * 64, 100);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// mode retained over close
|
// mode retained over close
|
||||||
@@ -2341,7 +2346,8 @@ public class DeviceTest {
|
|||||||
assertEquals(flowControl, usb.serialPort.getFlowControl());
|
assertEquals(flowControl, usb.serialPort.getFlowControl());
|
||||||
assertTrue(m ? usb.serialPort.getRTS() : usb.serialPort.getDTR());
|
assertTrue(m ? usb.serialPort.getRTS() : usb.serialPort.getDTR());
|
||||||
assertTrue(usb.serialPort.getControlLines().contains(m ? ControlLine.CTS : ControlLine.DSR));
|
assertTrue(usb.serialPort.getControlLines().contains(m ? ControlLine.CTS : ControlLine.DSR));
|
||||||
new NoRead().run();
|
if (inputFlowControl)
|
||||||
|
new NoRead().run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
+3
-2
@@ -135,8 +135,9 @@ public class UsbWrapper implements SerialInputOutputManager.Listener {
|
|||||||
} else if (serialDriver instanceof Ch34xSerialDriver) {
|
} else if (serialDriver instanceof Ch34xSerialDriver) {
|
||||||
outputLinesSupported = true;
|
outputLinesSupported = true;
|
||||||
inputLinesSupported = true;
|
inputLinesSupported = true;
|
||||||
if(serialDriver.getDevice().getProductId() == UsbId.QINHENG_CH340)
|
inputLinesConnected = true;
|
||||||
inputLinesConnected = true; // I only have 74LS138 connected at CH340, not connected at CH341A
|
if(serialDriver.getDevice().getProductId() == UsbId.QINHENG_CH341A)
|
||||||
|
inputLinesOnlyRtsCts = true;
|
||||||
} else if (serialDriver instanceof CdcAcmSerialDriver) {
|
} else if (serialDriver instanceof CdcAcmSerialDriver) {
|
||||||
outputLinesSupported = true;
|
outputLinesSupported = true;
|
||||||
inputLinesSupported = true;
|
inputLinesSupported = true;
|
||||||
|
|||||||
+22
@@ -101,6 +101,7 @@ public class Ch34xSerialDriver implements UsbSerialDriver {
|
|||||||
|
|
||||||
initialize();
|
initialize();
|
||||||
setBaudRate(DEFAULT_BAUD_RATE);
|
setBaudRate(DEFAULT_BAUD_RATE);
|
||||||
|
setFlowControl(mFlowControl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -357,6 +358,27 @@ public class Ch34xSerialDriver implements UsbSerialDriver {
|
|||||||
return EnumSet.allOf(ControlLine.class);
|
return EnumSet.allOf(ControlLine.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFlowControl(FlowControl flowControl) throws IOException {
|
||||||
|
if (flowControl == FlowControl.RTS_CTS) {
|
||||||
|
if (controlOut(0x9a, 0x2727, 0x0101) < 0) {
|
||||||
|
throw new IOException("Error setting flow control");
|
||||||
|
}
|
||||||
|
} else if (flowControl == FlowControl.NONE) {
|
||||||
|
if (controlOut(0x9a, 0x2727, 0x0000) < 0) {
|
||||||
|
throw new IOException("Error setting flow control");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new UnsupportedOperationException("Unsupported flow control: " + flowControl);
|
||||||
|
}
|
||||||
|
mFlowControl = flowControl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<FlowControl> getSupportedFlowControl() {
|
||||||
|
return EnumSet.of(FlowControl.NONE, FlowControl.RTS_CTS);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBreak(boolean value) throws IOException {
|
public void setBreak(boolean value) throws IOException {
|
||||||
byte[] req = new byte[2];
|
byte[] req = new byte[2];
|
||||||
|
|||||||
Reference in New Issue
Block a user