implement CP21xx input control lines

open() CP21xx without RTS, DTR set
pull/297/head v2.3.0
kai-morich 2020-06-30 20:13:17 +02:00
rodzic 7423fd9d79
commit a1e58b9843
3 zmienionych plików z 62 dodań i 40 usunięć

Wyświetl plik

@ -22,7 +22,7 @@ dependencies {
androidTestImplementation 'com.android.support:support-annotations:28.0.0'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'commons-net:commons-net:3.6'
androidTestImplementation 'org.apache.commons:commons-lang3:3.8.1'
androidTestImplementation 'org.apache.commons:commons-lang3:3.8.1' // starting with 3.9 requires min-api 26
}
//apply from: 'publishToMavenLocal.gradle'

Wyświetl plik

@ -61,6 +61,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Executors;
import static org.hamcrest.CoreMatchers.anyOf;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@ -1240,13 +1241,17 @@ public class DeviceTest implements SerialInputOutputManager.Listener {
Thread.sleep(50);
while(data.length()==0 || data.charAt(data.length()-1)!='d')
data.append(new String(telnetRead()));
Log.i(TAG, "purgeHwBuffers " + purged + ": " + buf.length+1 + " -> " + data.length());
Log.i(TAG, "purgeHwBuffers " + purged + ": " + (buf.length+3) + " -> " + data.length());
assertTrue(data.length() > 5);
if(purged)
assertTrue(data.length() < buf.length+1);
else
if(purged) {
if(usbSerialDriver instanceof Cp21xxSerialDriver && usbSerialDriver.getPorts().size() == 1) // only working on some devices/ports
assertTrue(data.length() < buf.length + 1 || data.length() == buf.length + 3);
else
assertTrue(data.length() < buf.length + 1);
} else {
assertEquals(data.length(), buf.length + 3);
}
// purge read buffer
usbClose();
@ -1266,7 +1271,8 @@ public class DeviceTest implements SerialInputOutputManager.Listener {
} else if(usbSerialDriver.getPorts().size() > 1) {
assertThat(usbRead(1), equalTo("y".getBytes())); // cp2105/0
} else {
assertThat(usbRead(2), equalTo("xy".getBytes())); // cp2102
assertThat(usbRead(2), anyOf(equalTo("xy".getBytes()), // cp2102
equalTo("y".getBytes()))); // cp2102
}
} else {
assertThat(usbRead(1), equalTo("y".getBytes()));
@ -1408,6 +1414,7 @@ public class DeviceTest implements SerialInputOutputManager.Listener {
usbClose();
// date loss with high transfer rate and short read timeout !!!
diffLen = readSpeedInt(5, shortTimeout);
assertNotEquals(0, diffLen);
// data loss observed with read timeout up to 200 msec, e.g.
@ -1498,7 +1505,7 @@ public class DeviceTest implements SerialInputOutputManager.Listener {
wrongSerialPort.open(wrongDeviceConnection);
if(usbSerialDriver instanceof Cp21xxSerialDriver)
wrongSerialPort.setParameters(115200, UsbSerialPort.DATABITS_8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE); // ch340 fails here
fail("error expected");
//fail("error expected"); // only fails on some devices
} catch (IOException ignored) {
}
try {
@ -1552,11 +1559,15 @@ public class DeviceTest implements SerialInputOutputManager.Listener {
int sleep = 10;
// output lines are supported by all drivers
// input lines are supported by all drivers except CDC
boolean inputLinesSupported = false;
boolean inputLinesConnected = false;
if (usbSerialDriver instanceof FtdiSerialDriver) {
inputLinesSupported = true;
inputLinesConnected = usbSerialDriver.getPorts().size()==2; // I only have 74LS138 connected at FT2232
inputLinesConnected = usbSerialDriver.getPorts().size() == 2; // I only have 74LS138 connected at FT2232
} else if (usbSerialDriver instanceof Cp21xxSerialDriver) {
inputLinesSupported = true;
inputLinesConnected = usbSerialDriver.getPorts().size()==1; // I only have 74LS138 connected at CP2102
} else if (usbSerialDriver instanceof ProlificSerialDriver) {
inputLinesSupported = true;
inputLinesConnected = true;
@ -1572,6 +1583,9 @@ public class DeviceTest implements SerialInputOutputManager.Listener {
supportedControlLines.add(UsbSerialPort.ControlLine.RI);
}
// UsbSerialProber creates new UsbSerialPort objects which resets control lines,
// so the initial open has the output control lines unset.
// On additional close+open the output control lines can be retained.
usbOpen(EnumSet.of(UsbOpenFlags.NO_CONTROL_LINE_INIT));
usbParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE);
telnetParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE);
@ -1586,6 +1600,8 @@ public class DeviceTest implements SerialInputOutputManager.Listener {
Thread.sleep(sleep);
assertTrue(usbSerialPort.getRI());
}
// control lines reset on initial open
data = "none".getBytes();
assertEquals(inputLinesConnected
? EnumSet.of(UsbSerialPort.ControlLine.RI)
@ -1661,7 +1677,7 @@ public class DeviceTest implements SerialInputOutputManager.Listener {
usbWrite(data);
assertThat(Arrays.toString(data), telnetRead(4), equalTo(data));
// state retained over close/open
// control lines retained over close+open
boolean inputRetained = inputLinesConnected;
boolean outputRetained = true;
if(usbSerialDriver instanceof FtdiSerialDriver)

Wyświetl plik

@ -61,28 +61,26 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
public class Cp21xxSerialPort extends CommonUsbSerialPort {
private static final int DEFAULT_BAUD_RATE = 9600;
private static final int USB_WRITE_TIMEOUT_MILLIS = 5000;
/*
* Configuration Request Types
*/
private static final int REQTYPE_HOST_TO_DEVICE = 0x41;
private static final int REQTYPE_DEVICE_TO_HOST = 0xc1;
/*
* Configuration Request Codes
*/
private static final int SILABSER_IFC_ENABLE_REQUEST_CODE = 0x00;
private static final int SILABSER_SET_BAUDDIV_REQUEST_CODE = 0x01;
private static final int SILABSER_SET_LINE_CTL_REQUEST_CODE = 0x03;
private static final int SILABSER_SET_MHS_REQUEST_CODE = 0x07;
private static final int SILABSER_SET_BAUDRATE = 0x1E;
private static final int SILABSER_FLUSH_REQUEST_CODE = 0x12;
private static final int SILABSER_SET_DTR_RTS_REQUEST_CODE = 0x07;
private static final int SILABSER_GET_MDMSTS_REQUEST_CODE = 0x08;
private static final int FLUSH_READ_CODE = 0x0a;
private static final int FLUSH_WRITE_CODE = 0x05;
private static final int FLUSH_READ_CODE = 0x0a;
private static final int FLUSH_WRITE_CODE = 0x05;
/*
* SILABSER_IFC_ENABLE_REQUEST_CODE
@ -90,29 +88,23 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
private static final int UART_ENABLE = 0x0001;
private static final int UART_DISABLE = 0x0000;
/*
* SILABSER_SET_BAUDDIV_REQUEST_CODE
*/
private static final int BAUD_RATE_GEN_FREQ = 0x384000;
/*
* SILABSER_SET_MHS_REQUEST_CODE
*/
private static final int MCR_DTR = 0x0001;
private static final int MCR_RTS = 0x0002;
private static final int MCR_ALL = 0x0003;
private static final int CONTROL_WRITE_DTR = 0x0100;
private static final int CONTROL_WRITE_RTS = 0x0200;
/*
* SILABSER_SET_DTR_RTS_REQUEST_CODE
*/
private static final int DTR_ENABLE = 0x101;
private static final int DTR_DISABLE = 0x100;
private static final int RTS_ENABLE = 0x202;
private static final int RTS_DISABLE = 0x200;
/*
* SILABSER_GET_MDMSTS_REQUEST_CODE
*/
private static final int STATUS_CTS = 0x10;
private static final int STATUS_DSR = 0x20;
private static final int STATUS_RI = 0x40;
private static final int STATUS_CD = 0x80;
private boolean dtr = false;
private boolean rts = false;
@ -137,6 +129,16 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
}
}
private byte getStatus() throws IOException {
byte[] buffer = new byte[1];
int result = mConnection.controlTransfer(REQTYPE_DEVICE_TO_HOST, SILABSER_GET_MDMSTS_REQUEST_CODE, 0,
mPortNumber, buffer, buffer.length, USB_WRITE_TIMEOUT_MILLIS);
if (result != 1) {
throw new IOException("Control transfer failed: " + SILABSER_GET_MDMSTS_REQUEST_CODE + " / " + 0 + " -> " + result);
}
return buffer[0];
}
@Override
protected void openInt(UsbDeviceConnection connection) throws IOException {
mIsRestrictedPort = mDevice.getInterfaceCount() == 2 && mPortNumber == 1;
@ -159,9 +161,7 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
}
setConfigSingle(SILABSER_IFC_ENABLE_REQUEST_CODE, UART_ENABLE);
setConfigSingle(SILABSER_SET_MHS_REQUEST_CODE, MCR_ALL | CONTROL_WRITE_DTR | CONTROL_WRITE_RTS);
// setConfigSingle(SILABSER_SET_BAUDDIV_REQUEST_CODE, BAUD_RATE_GEN_FREQ / DEFAULT_BAUD_RATE);
// setParameters(DEFAULT_BAUD_RATE, DEFAULT_DATA_BITS, DEFAULT_STOP_BITS, DEFAULT_PARITY);
setConfigSingle(SILABSER_SET_MHS_REQUEST_CODE, (dtr ? DTR_ENABLE : DTR_DISABLE) | (rts ? RTS_ENABLE : RTS_DISABLE));
}
@Override
@ -260,17 +260,17 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
@Override
public boolean getCD() throws IOException {
return false;
return (getStatus() & STATUS_CD) != 0;
}
@Override
public boolean getCTS() throws IOException {
return false;
return (getStatus() & STATUS_CTS) != 0;
}
@Override
public boolean getDSR() throws IOException {
return false;
return (getStatus() & STATUS_DSR) != 0;
}
@Override
@ -281,12 +281,12 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
@Override
public void setDTR(boolean value) throws IOException {
dtr = value;
setConfigSingle(SILABSER_SET_DTR_RTS_REQUEST_CODE, dtr ? DTR_ENABLE : DTR_DISABLE);
setConfigSingle(SILABSER_SET_MHS_REQUEST_CODE, dtr ? DTR_ENABLE : DTR_DISABLE);
}
@Override
public boolean getRI() throws IOException {
return false;
return (getStatus() & STATUS_RI) != 0;
}
@Override
@ -297,23 +297,29 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
@Override
public void setRTS(boolean value) throws IOException {
rts = value;
setConfigSingle(SILABSER_SET_DTR_RTS_REQUEST_CODE, rts ? RTS_ENABLE : RTS_DISABLE);
setConfigSingle(SILABSER_SET_MHS_REQUEST_CODE, rts ? RTS_ENABLE : RTS_DISABLE);
}
@Override
public EnumSet<ControlLine> getControlLines() throws IOException {
byte status = getStatus();
EnumSet<ControlLine> set = EnumSet.noneOf(ControlLine.class);
if(rts) set.add(ControlLine.RTS);
if((status & STATUS_CTS) != 0) set.add(ControlLine.CTS);
if(dtr) set.add(ControlLine.DTR);
if((status & STATUS_DSR) != 0) set.add(ControlLine.DSR);
if((status & STATUS_CD) != 0) set.add(ControlLine.CD);
if((status & STATUS_RI) != 0) set.add(ControlLine.RI);
return set;
}
@Override
public EnumSet<ControlLine> getSupportedControlLines() throws IOException {
return EnumSet.of(ControlLine.RTS, ControlLine.DTR);
return EnumSet.allOf(ControlLine.class);
}
@Override
// note: only working on some devices, on other devices ignored w/o error
public boolean purgeHwBuffers(boolean purgeWriteBuffers, boolean purgeReadBuffers) throws IOException {
int value = (purgeReadBuffers ? FLUSH_READ_CODE : 0)
| (purgeWriteBuffers ? FLUSH_WRITE_CODE : 0);