Fazecast / jSerialComm

Platform-independent serial port access for Java
GNU Lesser General Public License v3.0
1.35k stars 287 forks source link

Unable to reset ixoff flag #365

Closed ilpk closed 2 years ago

ilpk commented 3 years ago

I have been having trouble communicating with a device that uses no flow control, and I think that the problem is due to the way jSerialComm handles the XON/XOFF flags (Linux, jSerialComm 2.6.2). The ixoff flag is occasionally switched on on my computer before the Java program starts up. In SerialPort_Posix.c line 274, Java_com_fazecast_jSerialComm_SerialPort_openPortNative, the serial port is opened to a sane default: options.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); I suspect that IXOFF should also be in the list.

The other half of the problem is in Java_com_fazecast_jSerialComm_SerialPort_configPort, line 350, where we see: options.c_iflag |= (XonXoffInEnabled | XonXoffOutEnabled); This allows us to enable these flags, but not to disable them, since setting the values to 0 leaves the flags unchanged.

Is this a program bug, or am I missing something?

Best wishes,

Paul

hedgecrw commented 3 years ago

This does appear to be a bug...good catch! Please test the following pre-release version and see if it resolves your issue:

https://drive.google.com/file/d/11jqbkGWJA26GW_pS5fcq02LHFWkWZot4/view?usp=sharing

ilpk commented 3 years ago

Unfortunately it appears to make no difference. I used the small test program below:

import com.fazecast.jSerialComm.SerialPort;

public class TestSerial { public static void main(String[] args) { SerialPort serialPort = null;

for (SerialPort device : SerialPort.getCommPorts()) {
  if (device.getSystemPortName().toLowerCase().endsWith("ttyusb0")) {
    serialPort = device;
    break;
  }
}

serialPort.openPort(100);

System.out.println("Serial port open:" + serialPort.getSystemPortName());
try {Thread.sleep(10000);} catch (Exception e) {}

serialPort.setBaudRate(9600);
serialPort.setNumDataBits(8);
serialPort.setNumStopBits(1);
serialPort.setParity(SerialPort.NO_PARITY);
serialPort.setFlowControl(SerialPort.FLOW_CONTROL_DISABLED);

System.out.println("Serial port no flow control");
try {Thread.sleep(10000);} catch (Exception e) {}

serialPort.setBaudRate(9600);
serialPort.setNumDataBits(8);
serialPort.setNumStopBits(1);
serialPort.setParity(SerialPort.NO_PARITY);
serialPort.setFlowControl(SerialPort.FLOW_CONTROL_XONXOFF_IN_ENABLED | SerialPort.FLOW_CONTROL_XONXOFF_OUT_ENABLED);

System.out.println("Serial port XON/XOFF");
try {Thread.sleep(10000);} catch (Exception e) {}

serialPort.setBaudRate(9600);
serialPort.setNumDataBits(8);
serialPort.setNumStopBits(1);
serialPort.setParity(SerialPort.NO_PARITY);
serialPort.setFlowControl(SerialPort.FLOW_CONTROL_DISABLED);

System.out.println("Serial port no flow control");
try {Thread.sleep(10000);} catch (Exception e) {}

} }

Running an 'stty -F /dev/ttyUSB0' from the command line during each of the 10 second pauses gives the following result:

After open ...

stty -F /dev/ttyUSB0

speed 9600 baud; line = 0; intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = ; eol2 = ; swtch = ; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 0; time = 0; -icrnl -imaxbel -opost -isig -icanon -iexten -echo

After no flow control

stty -F /dev/ttyUSB0

speed 9600 baud; line = 0; intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = ; eol2 = ; swtch = ; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 0; time = 0; -icrnl -imaxbel -opost -isig -icanon -iexten -echo

After xon/xoff

stty -F /dev/ttyUSB0

speed 9600 baud; line = 0; intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = ; eol2 = ; swtch = ; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 0; time = 0; -icrnl ixoff -imaxbel -opost -isig -icanon -iexten -echo

After no flow control

stty -F /dev/ttyUSB0

speed 9600 baud; line = 0; intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = ; eol2 = ; swtch = ; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 0; time = 0; -icrnl ixoff -imaxbel -opost -isig -icanon -iexten -echo

The xon/xoff flags appear to never get cleared. If I set them by hand before starting the test program (e.g. stty -F /dev/ttyUSB0 ixoff) then the flags do not get cleared when the serial port is opened, and also not when the flow control is set to none.

I am using the jSerialComm-2.8.0.jar you sent, with an md5sum of 1651803ff5409105740ed31523a9b310

hedgecrw commented 3 years ago

Please test the attached library version and see if it works any better for you. There have been a ton of recent changes that have not made it into an actual release yet. Thanks!

https://drive.google.com/file/d/1hH2hXCEj39WUN1iz3F1TzLrpNvUro_aL/view?usp=sharing

hedgecrw commented 3 years ago

Please use this version for testing: https://drive.google.com/file/d/1QzWPJg5MU_2YrnsB1MsOWeTbjYD84D2h/view?usp=sharing

ilpk commented 3 years ago

Hi Will,

I have tested again with jSerialComm-2.8.0-beta.jar and everything seems to work. Upon initialization the xon flag is cleared, and the program can set it on and off. Thank you for your support.

Best wishes,

Paul

hedgecrw commented 2 years ago

Solved in release of jSerialComm v2.8.0.