Index: SerialImp.c =================================================================== RCS file: /usr/local/cvsroot/rxtx-devel/src/SerialImp.c,v retrieving revision 1.46.2.187 diff -u -r1.46.2.187 SerialImp.c --- SerialImp.c 29 Jan 2006 22:19:04 -0000 1.46.2.187 +++ SerialImp.c 3 Jun 2006 23:12:40 -0000 @@ -793,6 +793,19 @@ result &= ~TIOCM_DTR; ioctl( fd, TIOCMSET, &result ); } + /* + B38400 is a special case in Linux for custom baud rates. + + We just treat this as a custom speed for now. If you take this ifdef + out and select baud rates 38400 then 28800 then 38400, you will get + a final baud rate of 28800 because you did not update the divisor. + + See the next ifdef below for the divisor. + */ +#if defined(TIOCGSERIAL) + if ( cspeed == B38400 ) + cspeed = 38400; +#endif /* TIOCGSERIAL */ if( cfsetispeed( &ttyset, cspeed ) < 0 || cfsetospeed( &ttyset, cspeed ) < 0 ) { @@ -814,6 +827,7 @@ */ #if defined(TIOCGSERIAL) + ioctl( fd, TIOCGSERIAL, &sstruct ); sstruct.custom_divisor = ( sstruct.baud_base/cspeed ); cspeed = B38400; #endif /* TIOCGSERIAL */ @@ -827,7 +841,7 @@ #if defined(TIOCSSERIAL) /* It is assumed Win32 does this for us */ if ( sstruct.baud_base < 1 || - ioctl( fd, TIOCSSERIAL, &sstruct ) < 0 ) + ioctl( fd, TIOCSSERIAL, &sstruct ) < 0 ) { return( 1 ); } Index: termios.c =================================================================== RCS file: /usr/local/cvsroot/rxtx-devel/src/termios.c,v retrieving revision 1.9.2.56 diff -u -r1.9.2.56 termios.c --- termios.c 16 Jan 2006 02:50:32 -0000 1.9.2.56 +++ termios.c 3 Jun 2006 23:12:40 -0000 @@ -323,8 +323,8 @@ case CBR_3500000: return( B3500000 ); case CBR_4000000: return( B4000000 ); default: - set_errno(EINVAL ); - return -1; + /* assume custom baudrate */ + return( Baud ); } } @@ -361,12 +361,13 @@ case B9600: ret = CBR_9600; break; case B14400: ret = CBR_14400; break; case B19200: ret = CBR_19200; break; + case B28800: ret = CBR_28800; break; case B38400: ret = CBR_38400; break; case B57600: ret = CBR_57600; break; case B115200: ret = CBR_115200; break; case B128000: ret = CBR_128000; break; - case B256000: ret = CBR_256000; break; case B230400: ret = CBR_230400; break; + case B256000: ret = CBR_256000; break; case B460800: ret = CBR_460800; break; case B500000: ret = CBR_500000; break; case B576000: ret = CBR_576000; break; @@ -381,10 +382,8 @@ case B4000000: ret = CBR_4000000; break; default: - fprintf( stderr, "B_to_CBR: invalid baudrate: %#o\n", - Baud ); - set_errno( EINVAL ); - return -1; + /* assume custom baudrate */ + return Baud; } LEAVE( "B_to_CBR" ); return ret; @@ -708,12 +707,9 @@ ENTER( "init_serial_struct" ); /* - FIXME - - This needs to use inb() to read the actual baud_base - and divisor from the UART registers. Question is how - far do we take this? - + use of custom_divisor and baud_base requires access to + kernel space. The kernel does try its best if you just + toss a baud rate at it though. */ sstruct->custom_divisor = 0; @@ -1678,16 +1674,17 @@ { char message[80]; ENTER( "cfsetospeed" ); + /* clear baudrate */ + s_termios->c_cflag &= ~CBAUD; if ( speed & ~CBAUD ) { sprintf( message, "cfsetospeed: not speed: %#o\n", speed ); report( message ); - return 0; + /* continue assuming its a custom baudrate */ + s_termios->c_cflag |= B38400; /* use 38400 during custom */ + s_termios->c_cflag |= CBAUDEX; /* use CBAUDEX for custom */ } - s_termios->c_ispeed = s_termios->c_ospeed = speed; - /* clear baudrate */ - s_termios->c_cflag &= ~CBAUD; - if( speed ) + else if( speed ) { s_termios->c_cflag |= speed; } @@ -1696,6 +1693,7 @@ /* PC blows up with speed 0 handled in Java */ s_termios->c_cflag |= B9600; } + s_termios->c_ispeed = s_termios->c_ospeed = speed; LEAVE( "cfsetospeed" ); return 1; } @@ -1767,25 +1765,6 @@ } /*---------------------------------------------------------- -serial_struct_to_DCB() - - accept: - perform: - return: - exceptions: - win32api: None - comments: -----------------------------------------------------------*/ -int serial_struct_to_DCB( struct serial_struct *sstruct, DCB *dcb ) -{ - /* 5 Baud rate fix - sstruct.baud_base - sstruct.custom_divisor = ( sstruct.baud_base/cspeed ); - */ - return(0); -} - -/*---------------------------------------------------------- termios_to_DCB() accept: @@ -1798,7 +1777,8 @@ int termios_to_DCB( struct termios *s_termios, DCB *dcb ) { ENTER( "termios_to_DCB" ); - s_termios->c_ispeed = s_termios->c_ospeed = s_termios->c_cflag & CBAUD; + if ( !(s_termios->c_cflag & CBAUDEX) ) + s_termios->c_ispeed = s_termios->c_ospeed = s_termios->c_cflag & CBAUD; dcb->BaudRate = B_to_CBR( s_termios->c_ispeed ); dcb->ByteSize = termios_to_bytesize( s_termios->c_cflag ); @@ -2863,11 +2843,6 @@ GetCommState( index->hComm, dcb ); index->sstruct = va_arg( ap, struct serial_struct * ); - if ( serial_struct_to_DCB( index->sstruct, dcb ) < 0 ) - { - va_end( ap ); - return -1; - } report( "TIOCSSERIAL\n" ); free(dcb); Index: win32termios.h =================================================================== RCS file: /usr/local/cvsroot/rxtx-devel/src/win32termios.h,v retrieving revision 1.5.2.28 diff -u -r1.5.2.28 win32termios.h --- win32termios.h 30 Jun 2005 20:23:26 -0000 1.5.2.28 +++ win32termios.h 3 Jun 2006 23:12:40 -0000 @@ -279,7 +279,7 @@ #define XTABS 01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */ /* c_cflag bit meaning */ -# define CBAUD 0010017 +#define CBAUD 0030017 #define B0 0000000 /* hang up */ #define B50 0000001 #define B75 0000002 @@ -312,13 +312,16 @@ #define B3500000 0010016 #define B4000000 0010017 -/* glue for unsupported linux speeds see also SerialImp.h */ -/* hosed */ - -#define B14400 1010001 -#define B28800 1010002 -#define B128000 1010003 -#define B256000 1010004 +/* + glue for unsupported linux speeds see also SerialImp.h + custom baud rates around 8192-9000 will not work because + of these. +*/ + +#define B14400 0020001 +#define B28800 0020002 +#define B128000 0020003 +#define B256000 0020004 #define EXTA B19200 #define EXTB B38400 @@ -356,8 +359,10 @@ /* glue for unsupported windows speeds */ -#define CBR_230400 230400 #define CBR_28800 28800 +#define CBR_128000 128000 +#define CBR_230400 230400 +#define CBR_256000 256000 #define CBR_460800 460800 #define CBR_500000 500000 #define CBR_576000 576000