mirror of
https://github.com/mik3y/usb-serial-for-android.git
synced 2026-10-13 22:51:42 +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:
|
||||
groupId 'com.github.mik3y'
|
||||
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
|
||||
FlowControl_OutputLineLocked outputLineLocked = FlowControl_OutputLineLocked.FALSE;
|
||||
boolean outputLineSet = false;
|
||||
boolean inputFlowControl = true;
|
||||
if(usb.serialDriver instanceof ProlificSerialDriver) {
|
||||
outputLineSet = true; // line set to 'true' on setFlowControl
|
||||
outputLineLocked = FlowControl_OutputLineLocked.TRUE; // setRts/Dtr has no effect
|
||||
@@ -2197,7 +2198,9 @@ public class DeviceTest {
|
||||
if(usb.serialDriver instanceof FtdiSerialDriver) {
|
||||
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));
|
||||
telnet.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
|
||||
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
|
||||
// no read -> buffer full -> RTS/DTR off -> output line locked
|
||||
if (outputLineLocked != FlowControl_OutputLineLocked.TRUE) {
|
||||
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
|
||||
@@ -2341,7 +2346,8 @@ public class DeviceTest {
|
||||
assertEquals(flowControl, usb.serialPort.getFlowControl());
|
||||
assertTrue(m ? usb.serialPort.getRTS() : usb.serialPort.getDTR());
|
||||
assertTrue(usb.serialPort.getControlLines().contains(m ? ControlLine.CTS : ControlLine.DSR));
|
||||
new NoRead().run();
|
||||
if (inputFlowControl)
|
||||
new NoRead().run();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+3
-2
@@ -135,8 +135,9 @@ public class UsbWrapper implements SerialInputOutputManager.Listener {
|
||||
} else if (serialDriver instanceof Ch34xSerialDriver) {
|
||||
outputLinesSupported = true;
|
||||
inputLinesSupported = true;
|
||||
if(serialDriver.getDevice().getProductId() == UsbId.QINHENG_CH340)
|
||||
inputLinesConnected = true; // I only have 74LS138 connected at CH340, not connected at CH341A
|
||||
inputLinesConnected = true;
|
||||
if(serialDriver.getDevice().getProductId() == UsbId.QINHENG_CH341A)
|
||||
inputLinesOnlyRtsCts = true;
|
||||
} else if (serialDriver instanceof CdcAcmSerialDriver) {
|
||||
outputLinesSupported = true;
|
||||
inputLinesSupported = true;
|
||||
|
||||
+22
@@ -101,6 +101,7 @@ public class Ch34xSerialDriver implements UsbSerialDriver {
|
||||
|
||||
initialize();
|
||||
setBaudRate(DEFAULT_BAUD_RATE);
|
||||
setFlowControl(mFlowControl);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -357,6 +358,27 @@ public class Ch34xSerialDriver implements UsbSerialDriver {
|
||||
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
|
||||
public void setBreak(boolean value) throws IOException {
|
||||
byte[] req = new byte[2];
|
||||
|
||||
Reference in New Issue
Block a user