new setBreak() method

pull/330/head
kai-morich 2020-10-14 19:23:55 +02:00
rodzic 1e75f91467
commit 768f716600
10 zmienionych plików z 113 dodań i 2 usunięć

Wyświetl plik

@ -141,6 +141,25 @@ public class TerminalFragment extends Fragment implements SerialInputOutputManag
if (id == R.id.clear) {
receiveText.setText("");
return true;
} else if( id == R.id.send_break) {
if(!connected) {
Toast.makeText(getActivity(), "not connected", Toast.LENGTH_SHORT).show();
} else {
try {
usbSerialPort.setBreak(true);
Thread.sleep(100); // should show progress bar instead of blocking UI thread
usbSerialPort.setBreak(false);
SpannableStringBuilder spn = new SpannableStringBuilder();
spn.append("send <break>\n");
spn.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.colorSendText)), 0, spn.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
receiveText.append(spn);
} catch(UnsupportedOperationException ignored) {
Toast.makeText(getActivity(), "BREAK not supported", Toast.LENGTH_SHORT).show();
} catch(Exception e) {
Toast.makeText(getActivity(), "BREAK failed: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
return true;
} else {
return super.onOptionsItemSelected(item);
}

Wyświetl plik

@ -6,4 +6,8 @@
android:icon="@drawable/ic_delete_white_24dp"
android:title="Clear"
app:showAsAction="always" />
<item
android:id="@+id/send_break"
android:title="Send BREAK"
app:showAsAction="never" />
</menu>

Wyświetl plik

@ -1740,6 +1740,30 @@ public class DeviceTest {
}
}
@Test
public void setBreak() throws Exception {
usb.open();
telnet.setParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE);
usb.setParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE);
doReadWrite("");
usb.serialPort.setBreak(true);
Thread.sleep(100);
usb.serialPort.setBreak(false);
// RFC2217 has SET_CONTROL + REQ_BREAK_STATE request, but this is not supported by pyserial
// as there is no easy notification on <break> condition. By default break is returned as
// 0 byte on Linux, see https://man7.org/linux/man-pages/man3/termios.3.html -> BRKINT
byte[] data = telnet.read(1);
if (usb.serialDriver instanceof CdcAcmSerialDriver) {
// BREAK forwarding not implemented by arduino_leonardo_bridge.ino
assertThat("<break>", data, equalTo(new byte[]{}));
} else if(isCp21xxRestrictedPort) {
assertThat("<break>", data, equalTo(new byte[]{0x26})); // send the last byte again?
} else {
assertThat("<break>", data, equalTo(new byte[]{0}));
}
doReadWrite("");
}
@Test
public void deviceConnection() throws Exception {
byte[] buf = new byte[256];
@ -1813,6 +1837,11 @@ public class DeviceTest {
} catch (IOException ignored) {
}
}
try {
usb.serialPort.setBreak(true);
fail("setBreak error expected");
} catch (IOException ignored) {
}
usb.close();
try {
usb.open(EnumSet.of(UsbWrapper.OpenCloseFlags.NO_IOMANAGER_THREAD, UsbWrapper.OpenCloseFlags.NO_DEVICE_CONNECTION));

Wyświetl plik

@ -278,6 +278,12 @@ public class CdcAcmSerialDriver implements UsbSerialDriver {
public EnumSet<ControlLine> getSupportedControlLines() throws IOException {
return EnumSet.of(ControlLine.RTS, ControlLine.DTR);
}
@Override
public void setBreak(boolean value) throws IOException {
sendAcmControlMessage(SEND_BREAK, value ? 0xffff : 0, null);
}
}
public static Map<Integer, int[]> getSupportedDevices() {

Wyświetl plik

@ -341,6 +341,25 @@ public class Ch34xSerialDriver implements UsbSerialDriver {
public EnumSet<ControlLine> getSupportedControlLines() throws IOException {
return EnumSet.allOf(ControlLine.class);
}
@Override
public void setBreak(boolean value) throws IOException {
byte[] req = new byte[2];
if(controlIn(0x95, 0x1805, 0, req) < 0) {
throw new IOException("Error getting BREAK condition");
}
if(value) {
req[0] &= ~1;
req[1] &= ~0x40;
} else {
req[0] |= 1;
req[1] |= 0x40;
}
int val = (req[1] & 0xff) << 8 | (req[0] & 0xff);
if(controlOut(0x9a, 0x1805, val) < 0) {
throw new IOException("Error setting BREAK condition");
}
}
}
public static Map<Integer, int[]> getSupportedDevices() {

Wyświetl plik

@ -264,4 +264,7 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
throw new UnsupportedOperationException();
}
@Override
public void setBreak(boolean value) throws IOException { throw new UnsupportedOperationException(); }
}

Wyświetl plik

@ -59,6 +59,7 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
*/
private static final int SILABSER_IFC_ENABLE_REQUEST_CODE = 0x00;
private static final int SILABSER_SET_LINE_CTL_REQUEST_CODE = 0x03;
private static final int SILABSER_SET_BREAK_REQUEST_CODE = 0x05;
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;
@ -314,6 +315,10 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
}
}
@Override
public void setBreak(boolean value) throws IOException {
setConfigSingle(SILABSER_SET_BREAK_REQUEST_CODE, value ? 1 : 0);
}
}
public static Map<Integer, int[]> getSupportedDevices() {

Wyświetl plik

@ -84,6 +84,7 @@ public class FtdiSerialDriver implements UsbSerialDriver {
private boolean baudRateWithPort = false;
private boolean dtr = false;
private boolean rts = false;
private int breakConfig = 0;
public FtdiSerialPort(UsbDevice device, int portNumber) {
super(device, portNumber);
@ -280,6 +281,7 @@ public class FtdiSerialDriver implements UsbSerialDriver {
if (result != 0) {
throw new IOException("Setting parameters failed: result=" + result);
}
breakConfig = config;
}
private int getStatus() throws IOException {
@ -366,7 +368,7 @@ public class FtdiSerialDriver implements UsbSerialDriver {
int result = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, RESET_REQUEST,
RESET_PURGE_RX, mPortNumber+1, null, 0, USB_WRITE_TIMEOUT_MILLIS);
if (result != 0) {
throw new IOException("purge write buffer failed: result=" + result);
throw new IOException("Purge write buffer failed: result=" + result);
}
}
@ -374,11 +376,22 @@ public class FtdiSerialDriver implements UsbSerialDriver {
int result = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, RESET_REQUEST,
RESET_PURGE_TX, mPortNumber+1, null, 0, USB_WRITE_TIMEOUT_MILLIS);
if (result != 0) {
throw new IOException("purge read buffer failed: result=" + result);
throw new IOException("Purge read buffer failed: result=" + result);
}
}
}
@Override
public void setBreak(boolean value) throws IOException {
int config = breakConfig;
if(value) config |= 0x4000;
int result = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, SET_DATA_REQUEST,
config, mPortNumber+1,null, 0, USB_WRITE_TIMEOUT_MILLIS);
if (result != 0) {
throw new IOException("Setting BREAK failed: result=" + result);
}
}
public void setLatencyTimer(int latencyTime) throws IOException {
int result = mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, SET_LATENCY_TIMER_REQUEST,
latencyTime, mPortNumber+1, null, 0, USB_WRITE_TIMEOUT_MILLIS);

Wyświetl plik

@ -77,6 +77,7 @@ public class ProlificSerialDriver implements UsbSerialDriver {
private static final int SET_LINE_REQUEST = 0x20; // same as CDC SET_LINE_CODING
private static final int SET_CONTROL_REQUEST = 0x22; // same as CDC SET_CONTROL_LINE_STATE
private static final int SEND_BREAK_REQUEST = 0x23; // same as CDC SEND_BREAK
private static final int GET_CONTROL_REQUEST = 0x87;
private static final int STATUS_NOTIFICATION = 0xa1; // similar to CDC SERIAL_STATE but different length
@ -492,6 +493,11 @@ public class ProlificSerialDriver implements UsbSerialDriver {
vendorOut(FLUSH_TX_REQUEST, 0, null);
}
}
@Override
public void setBreak(boolean value) throws IOException {
ctrlOut(SEND_BREAK_REQUEST, value ? 0xffff : 0, 0, null);
}
}
public static Map<Integer, int[]> getSupportedDevices() {

Wyświetl plik

@ -248,6 +248,13 @@ public interface UsbSerialPort extends Closeable {
*/
public void purgeHwBuffers(boolean purgeWriteBuffers, boolean purgeReadBuffers) throws IOException;
/**
* send BREAK condition.
*
* @param value set/reset
*/
public void setBreak(boolean value) throws IOException;
/**
* Returns the current state of the connection.
*/