// note that this only supports baud rates defined in termios. int serial_connect(const char* portpath, int flags, speed_t baudrate) { speed_t new_baudrate; struct termios port_attrib; // termios attributes struct int fport = open(portpath,flags); if (fport == -1) { printf("Unable to open %s.\n", portpath); printf("Check that the device is plugged in and turned on.\n"); return -1; } // get the current port settings if (tcgetattr(fport, &port_attrib) < 0) { printf(" Failed to get port settings.\n"); close(fport); return -1; } // set raw mode cfmakeraw(&port_attrib); // set the baud rate to baudrate if (cfsetspeed(&port_attrib,baudrate) < 0) { printf(" Invalid baud rate specified or other baud rate error.\n"); close(fport); return -1;} // clear the serial line tcflush(fport, TCIOFLUSH); // apply the port settings (baud rate and raw mode) if (tcsetattr(fport,TCSANOW,&port_attrib) < 0) { printf(" Failed to apply new port settings.\n"); close(fport); return -1; } // try to get the new port settings if (tcgetattr(fport, &port_attrib) < 0) { printf(" Failed to get port settings.\n"); close(fport); return -1; } // print the new baud rate new_baudrate = cfgetospeed(&port_attrib); if (new_baudrate == baudrate) printf(" Port opened at baud rate: %d.\n",convert_baudrate(baudrate)); else { printf("Couldn't set baud rate.\n"); close(fport); return -1; } return fport; }
int COM_Setup(int fd, COM_PARAM param) { int ret = -1; struct termios termios_old; struct termios termios_new; int baudrate = 0; int fctl = 0; int databit = 0; int stopbit = 0; int parity = 0; if (fd < 0) { return -1; } bzero(&termios_old, sizeof(termios_old)); bzero(&termios_new, sizeof(termios_new)); cfmakeraw(&termios_new); tcgetattr(fd, &termios_old); // baudrates baudrate = convert_baudrate(param.nBaudRate); cfsetispeed(&termios_new, baudrate); cfsetospeed(&termios_new, baudrate); termios_new.c_cflag |= CLOCAL; termios_new.c_cflag |= CREAD; fctl = param.nFlowCtrl; switch (fctl) { case '0': termios_new.c_cflag &= ~CRTSCTS; // no flow control break; case '1': termios_new.c_cflag |= CRTSCTS; // hardware flow control break; case '2': termios_new.c_iflag |= IXON | IXOFF |IXANY; //software flow control break; } // data bits termios_new.c_cflag &= ~CSIZE; databit = param.nDataBits; switch (databit) { case '5': termios_new.c_cflag |= CS5; break; case '6': termios_new.c_cflag |= CS6; break; case '7': termios_new.c_cflag |= CS7; break; default: termios_new.c_cflag |= CS8; break; } // parity check parity = param.nParity; switch (parity) { case '0': termios_new.c_cflag &= ~PARENB; // no parity check break; case '1': termios_new.c_cflag |= PARENB; // odd check termios_new.c_cflag &= ~PARODD; break; case '2': termios_new.c_cflag |= PARENB; // even check termios_new.c_cflag |= PARODD; break; } // stop bits stopbit = param.nStopBits; if (stopbit == '2') { termios_new.c_cflag |= CSTOPB; // 2 stop bits } else { termios_new.c_cflag &= ~CSTOPB; // 1 stop bits } //other attributions default termios_new.c_oflag &= ~OPOST; termios_new.c_cc[VMIN] = 1; termios_new.c_cc[VTIME] = 1; // unit: (1/10)second tcflush(fd, TCIFLUSH); ret = tcsetattr(fd, TCSANOW, &termios_new); // TCSANOW tcgetattr(fd, &termios_old); return ret; }