Skip to content

Commit 391d0f5

Browse files
committed
add option disable_xonoff
1 parent 09c7635 commit 391d0f5

File tree

2 files changed

+43
-13
lines changed

2 files changed

+43
-13
lines changed

Source/Device/Serial.cpp

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -296,20 +296,16 @@ namespace Device
296296
throw std::runtime_error(std::string("Serial: cfsetispeed failed: ") + strerror(errno));
297297
}
298298

299-
// Control flags
299+
// ===== STEP 1: Control flags - set CLOCAL and CREAD first =====
300300
tty.c_cflag |= (CREAD | CLOCAL); // Enable receiver, ignore modem control lines
301-
tty.c_cflag &= ~PARENB; // No parity bit
302-
tty.c_cflag &= ~CSTOPB; // 1 stop bit
303-
tty.c_cflag &= ~CSIZE; // Clear all size bits
304-
tty.c_cflag |= CS8; // 8 bits per byte
305-
tty.c_cflag &= ~CRTSCTS; // Disable hardware flow control
306301

307-
// Local flags
302+
// ===== STEP 2: Local flags =====
308303
tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ISIG | IEXTEN);
309304

310-
// Input flags
311-
// CRITICAL: Do NOT touch IXON/IXOFF/IXANY - leave at system defaults
312-
// This is the key fix for FTDI compatibility
305+
// ===== STEP 3: Output flags =====
306+
tty.c_oflag &= ~OPOST; // Raw output - no processing
307+
308+
// ===== STEP 4: Input flags - initial clearing (NOT ISTRIP/INPCK yet) =====
313309
tty.c_iflag &= ~(INLCR | IGNCR | ICRNL | IGNBRK);
314310
#ifdef IUCLC
315311
tty.c_iflag &= ~IUCLC;
@@ -318,17 +314,47 @@ namespace Device
318314
tty.c_iflag &= ~PARMRK;
319315
#endif
320316

321-
tty.c_oflag &= ~OPOST; // Raw output - no processing
317+
// ===== STEP 5: Character size =====
318+
tty.c_cflag &= ~CSIZE; // Clear all size bits
319+
tty.c_cflag |= CS8; // 8 bits per byte
320+
321+
// ===== STEP 6: Stop bits =====
322+
tty.c_cflag &= ~CSTOPB; // 1 stop bit
323+
324+
// ===== STEP 7: Parity - and clear INPCK/ISTRIP here =====
325+
tty.c_iflag &= ~(INPCK | ISTRIP);
326+
tty.c_cflag &= ~(PARENB | PARODD); // No parity
322327

328+
// ===== STEP 8: Flow control =====
329+
// Hardware flow control
330+
tty.c_cflag &= ~CRTSCTS;
331+
332+
if (disable_xonxoff)
333+
{
334+
// Explicitly disable XON/XOFF
335+
#ifdef IXANY
336+
tty.c_iflag &= ~(IXON | IXOFF | IXANY);
337+
#else
338+
tty.c_iflag &= ~(IXON | IXOFF);
339+
#endif
340+
Info() << "Serial: XON/XOFF software flow control explicitly disabled" << std::endl;
341+
}
342+
else
343+
{
344+
Info() << "Serial: XON/XOFF software flow control left at system defaults" << std::endl;
345+
}
346+
347+
// ===== STEP 9: VMIN/VTIME =====
323348
tty.c_cc[VMIN] = 0;
324349
tty.c_cc[VTIME] = 0;
325350

351+
// ===== STEP 10: Apply settings =====
326352
if (tcsetattr(serial_fd, TCSANOW, &tty) < 0)
327353
{
328354
throw std::runtime_error(std::string("Serial: tcsetattr failed: ") + strerror(errno));
329355
}
330356

331-
// Flush buffers and stabilize
357+
// ===== POST-CONFIGURATION: Flush buffers and stabilize =====
332358
SleepSystem(200);
333359
tcflush(serial_fd, TCIOFLUSH);
334360

@@ -373,7 +399,6 @@ namespace Device
373399
lost = false;
374400
read_thread = std::thread(&SerialPort::ReadAsync, this);
375401
}
376-
377402
void SerialPort::Stop()
378403
{
379404
lost = true;
@@ -410,6 +435,10 @@ namespace Device
410435
{
411436
init_sequence = arg;
412437
}
438+
else if (option == "DISABLE_XONXOFF")
439+
{
440+
disable_xonxoff = Util::Parse::Switch(arg);
441+
}
413442
else
414443
Device::Set(option, arg);
415444

Source/Device/Serial.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ namespace Device
6666

6767
std::string port;
6868
int baudrate;
69+
bool disable_xonxoff = true;
6970

7071
std::thread read_thread;
7172

0 commit comments

Comments
 (0)