2828#include <sys/stat.h>
2929#include <sys/types.h>
3030#include <sys/wait.h>
31- #include <termios.h>
3231#include <unistd.h>
3332#else
3433#include <windows.h>
4039#endif
4140
4241#ifdef __linux__
42+ #include <asm/termbits.h>
4343#include <linux/serial.h>
44- #include <pty.h>
4544#endif
4645
4746#ifdef __APPLE__
47+ #include <termios.h>
4848#include <IOKit/serial/ioss.h>
4949#endif
5050
@@ -282,11 +282,12 @@ static int simple_uart_set_config(struct simple_uart *sc, int speed, const char
282282#if defined(__linux__ ) || defined(__APPLE__ )
283283static int simple_uart_set_config (struct simple_uart * sc , int speed , const char * mode_string ) // Linux Port config
284284{
285- struct termios options ; // Linux options handle
286- speed_t sp = B0 ; // Default linux speed
285+ speed_t sp = B0 ; // Default mac/linux speed
287286#ifdef __linux__
287+ struct termios2 options ; // Linux options handle
288288 int non_standard = 0 ;
289289#else // __APPLE__ type casting
290+ struct termios options ; // Mac options handle
290291 speed_t mac_speed = speed ;
291292#endif
292293
@@ -314,6 +315,11 @@ static int simple_uart_set_config(struct simple_uart *sc, int speed, const char
314315 case 3000000 : sp = B3000000 ; break ;
315316 case 3500000 : sp = B3500000 ; break ;
316317 case 4000000 : sp = B4000000 ; break ;
318+
319+ /* These speeds are supported on Linux via termios2, e.g. on FTDI */
320+ case 6000000 : sp = 6000000 ; break ;
321+ case 12000000 : sp = 12000000 ; break ;
322+
317323 default : sp = B38400 ; non_standard = 1 ;
318324#else // __APPLE__ only
319325 // The IOSSIOSPEED ioctl can be used to set arbitrary baud rates
@@ -327,14 +333,41 @@ static int simple_uart_set_config(struct simple_uart *sc, int speed, const char
327333 }
328334#endif
329335 }
330- /* Accquire current port config */
336+
337+ /* Acquire current port config */
338+ #ifdef __linux__
339+ if (ioctl (sc -> fd , TCGETS2 , & options ) < 0 )
340+ return - errno ;
341+ #else
331342 if (tcgetattr (sc -> fd , & options ) < 0 )
332343 return - errno ;
344+ #endif
333345
346+ #ifdef __linux__
347+ options .c_cflag &= ~CBAUD ;
348+ if ((speed >= 6000000 ) && (speed <= 12000000 ))
349+ {
350+ /* Use the BOTHER/CBAUDEX flag for high speeds */
351+ options .c_cflag |= BOTHER ;
352+ options .c_cflag |= CBAUDEX ;
353+ options .c_ispeed = sp ;
354+ options .c_ospeed = sp ;
355+ }
356+ else
357+ {
358+ /* Normal options */
359+ options .c_cflag &= ~BOTHER ;
360+ options .c_cflag &= ~CBAUDEX ;
361+ options .c_cflag |= sp ;
362+ options .c_ispeed = 0 ;
363+ options .c_ospeed = 0 ;
364+ }
365+ #else
334366 if (sp != 0 ) {
335367 cfsetospeed (& options , sp );
336368 cfsetispeed (& options , sp );
337369 }
370+ #endif
338371
339372 options .c_cflag &= (tcflag_t ) ~(HUPCL );
340373
@@ -392,9 +425,21 @@ static int simple_uart_set_config(struct simple_uart *sc, int speed, const char
392425
393426 options .c_cc [VTIME ] = 0 ;
394427 options .c_cc [VMIN ] = 0 ;
428+
429+ #ifdef __linux__
430+ if (ioctl (sc -> fd , TCFLSH , TCIOFLUSH ) < 0 )
431+ return - errno ;
432+ #else
395433 tcflush (sc -> fd , TCIOFLUSH );
434+ #endif
435+
436+ #ifdef __linux__
437+ if (ioctl (sc -> fd , TCSETS2 , & options ) < 0 )
438+ return - errno ;
439+ #else
396440 if (tcsetattr (sc -> fd , TCSANOW , & options ) < 0 )
397441 return - errno ;
442+ #endif
398443
399444#ifdef __linux__
400445 if (HAS_OPTION ('R' )) {
@@ -839,17 +884,20 @@ int simple_uart_send_break(struct simple_uart *uart)
839884 if (!uart )
840885 return - EINVAL ;
841886
842- #if defined(__linux__ ) || defined(__APPLE__ )
843- tcsendbreak (uart -> fd , 1 );
844- return 0 ;
887+ #ifdef __linux__
888+ if (ioctl (uart -> fd , TCSBRK , 1 ) < 0 )
889+ return - errno ;
890+ #elif defined(__APPLE__ )
891+ if (tcsendbreak (uart -> fd , 1 ) < 0 )
892+ return - errno ;
845893#else
846894 SetCommBreak (uart -> port );
847895 // Linux doesn't support durations, it is always 4/10 of a second.
848896 // Replicate that here.
849897 Sleep (400 );
850898 ClearCommBreak (uart -> port );
851- return 0 ;
852899#endif
900+ return 0 ;
853901}
854902
855903#ifdef _WIN32
@@ -938,7 +986,10 @@ int simple_uart_flush(struct simple_uart *uart)
938986 if (!uart )
939987 return - EINVAL ;
940988
941- #if defined(__linux__ ) || defined(__APPLE__ )
989+ #if defined(__linux__ )
990+ if (ioctl (uart -> fd , TCFLSH , TCIOFLUSH ) < 0 )
991+ return - errno ;
992+ #elif defined(__APPLE__ )
942993 if (tcdrain (uart -> fd ) < 0 )
943994 return - errno ;
944995#else
0 commit comments