diff --git a/common.c b/common.c index 12ba671..7f9d887 100644 --- a/common.c +++ b/common.c @@ -22,12 +22,16 @@ #include "common.h" #include +#include +#include +#include int setserial(struct termios *cfg, int ser_fd, int baud, int databits, char parity, int stopbits, int hw_flow, int sw_flow, int modemlines) { int rval = 0; + int custom = 0; rval = tcgetattr(ser_fd, cfg); if (rval) goto done; @@ -56,11 +60,23 @@ int setserial(struct termios *cfg, int ser_fd, int baud, SERIAL_BAUD_CASE(57600); SERIAL_BAUD_CASE(115200); SERIAL_BAUD_CASE(230400); + SERIAL_BAUD_CASE(460800); + SERIAL_BAUD_CASE(576000); + SERIAL_BAUD_CASE(921600); + SERIAL_BAUD_CASE(1000000); + SERIAL_BAUD_CASE(1152000); + SERIAL_BAUD_CASE(1500000); + SERIAL_BAUD_CASE(2000000); + SERIAL_BAUD_CASE(2500000); + SERIAL_BAUD_CASE(3000000); + SERIAL_BAUD_CASE(3500000); + SERIAL_BAUD_CASE(4000000); default: - fprintf(stderr, "Invalid serial baud rate specified (%d)\n", + fprintf(stderr, "Non-standard baud rate specified; may not function (%d)\n", baud); - rval = 1; - goto done; + cfsetispeed(cfg, B38400); + cfsetospeed(cfg, B38400); + custom = 1; } parity &= ~0x20; /* make things case insensitive */ @@ -138,9 +154,24 @@ int setserial(struct termios *cfg, int ser_fd, int baud, rval = tcsetattr(ser_fd, TCSANOW, cfg); if (rval) goto done; + if (custom) { + struct serial_struct serinfo; + + if (ioctl(ser_fd, TIOCGSERIAL, &serinfo) < 0) { + perror("Can't get serial info:"); + goto done; + } + serinfo.flags &= ~ASYNC_SPD_MASK; + serinfo.flags |= ASYNC_SPD_CUST; + serinfo.custom_divisor = serinfo.baud_base / baud; + if (ioctl(ser_fd, TIOCSSERIAL, &serinfo) < 0) { + perror("Can't set serial info:"); + goto done; + } + } + done: if (rval) fprintf(stderr, "ERROR.. %d\n", rval); - { struct termios cfg2; tcgetattr(ser_fd, &cfg2);