/** Set the baud rate, where the baudrate is just the integer value desired. Returns non-zero on error. **/ int serial_set_baud (int fd, int baudrate) { struct termios tios; #ifdef SUPPORT_HISPEED struct serial_struct ser; #endif int baudratecode = serial_translate_baud (baudrate); if (baudratecode > 0) { // standard baud rate. tcgetattr (fd, &tios); cfsetispeed (&tios, baudratecode); cfsetospeed (&tios, baudratecode); tcflush (fd, TCIFLUSH); tcsetattr (fd, TCSANOW, &tios); #ifdef SUPPORT_HISPEED ioctl (fd, TIOCGSERIAL, &ser); ser.flags = (ser.flags&(~ASYNC_SPD_MASK)); ser.custom_divisor = 0; ioctl (fd, TIOCSSERIAL, &ser); #endif } else { // non-standard baud rate. #ifdef SUPPORT_HISPEED // printf("Setting custom divisor\n"); if (tcgetattr (fd, &tios)) perror ("tcgetattr"); cfsetispeed (&tios, B38400); cfsetospeed (&tios, B38400); tcflush (fd, TCIFLUSH); if (tcsetattr (fd, TCSANOW, &tios)) perror ("tcsetattr"); if (ioctl (fd, TIOCGSERIAL, &ser)) perror ("ioctl TIOCGSERIAL"); ser.flags = (ser.flags&(~ASYNC_SPD_MASK)) | ASYNC_SPD_CUST; ser.custom_divisor = (ser.baud_base + baudrate/2)/baudrate; ser.reserved_char[0] = 0; // what the hell does this do? // printf("baud_base %i\ndivisor %i\n", ser.baud_base,ser.custom_divisor); if (ioctl (fd, TIOCSSERIAL, &ser)) perror ("ioctl TIOCSSERIAL"); #endif } tcflush (fd, TCIFLUSH); return 0; }
/** Creates a basic fd, setting baud to 9600, raw data i/o (no flow control, no fancy character handling. Configures it for blocking reads. Returns the fd, -1 on error **/ int serial_open(const char *port, int baud, int blocking) { struct termios opts; int flags = O_RDWR | O_NOCTTY; if (!blocking) flags |= O_NONBLOCK; int fd=open(port, flags, 0); if (fd==-1) return -1; if (tcgetattr(fd, &opts)) { printf("*** %i\n",fd); perror("tcgetattr"); return -1; } cfsetispeed(&opts, serial_translate_baud(9600)); cfsetospeed(&opts, serial_translate_baud(9600)); cfmakeraw(&opts); // set one stop bit opts.c_cflag &= ~CSTOPB; if (tcsetattr(fd,TCSANOW,&opts)) { perror("tcsetattr"); return -1; } tcflush(fd, TCIOFLUSH); serial_set_baud(fd, baud); return fd; }