@@ -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
0 commit comments