int serial_init(int fd, long speed) { struct termios attribs; // Initialize attribs if(tcgetattr(fd, &attribs) < 0) { close(fd); return SERIAL_INVALID_FILEDESC; } /* Set speed */ { speed_t cfspeed = ntocf(speed); if(cfsetispeed(&attribs, cfspeed) < 0) { return SERIAL_INVALID_SPEED; } serial_set_attrib(fd, &attribs); if(cfsetospeed(&attribs, cfspeed) < 0) { return SERIAL_INVALID_SPEED; } serial_set_attrib(fd, &attribs); } /* Set non-canonical mode */ int status; attribs.c_cc[VTIME] = 0; if((status = serial_set_attrib(fd, &attribs)) < 0) { return status; } attribs.c_cc[VMIN] = 0; if((status = serial_set_attrib(fd, &attribs)) < 0) { return status; } cfmakeraw(&attribs); if((status = serial_set_attrib(fd, &attribs)) < 0) { return status; } /* Prevents DTR from being dropped, resetting the MCU when using * an Arduino bootloader */ attribs.c_cflag &= ~HUPCL; if((status = serial_set_attrib(fd, &attribs)) < 0) { return status; } return SERIAL_NO_ERROR; }
static int serial_init(int fd, long speed, char **detail) { int status; struct termios attribs; // Initialize attribs if(tcgetattr(fd, &attribs) < 0) { int tmp = errno; *detail = "not a serial device"; close(fd); errno = tmp; return -1; } /* Handle software flow control bytes from machine */ attribs.c_iflag |= IXOFF; serial_set_attrib(fd, &attribs); if((status = serial_set_attrib(fd, &attribs)) < 0) { *detail = "serial device has no flow control"; return status; } /* Set speed */ { speed_t cfspeed = ntocf(speed); if(cfsetispeed(&attribs, cfspeed) < 0) { #ifdef __linux__ return linux_set_speed_custom(fd, speed); #else *detail = "can't set input speed"; return -1; #endif } serial_set_attrib(fd, &attribs); if(cfsetospeed(&attribs, cfspeed) < 0) { *detail = "can't set ouput speed"; return -1; } serial_set_attrib(fd, &attribs); } /* Set non-canonical mode */ attribs.c_cc[VTIME] = 0; if((status = serial_set_attrib(fd, &attribs)) < 0) { *detail = "can't set non-canonical mode (vtime)"; return status; } attribs.c_cc[VMIN] = 0; if((status = serial_set_attrib(fd, &attribs)) < 0) { *detail = "can't set non-canonical mode (vmin)"; return status; } cfmakeraw(&attribs); if((status = serial_set_attrib(fd, &attribs)) < 0) { *detail = "can't set raw mode"; return status; } /* Prevents DTR from being dropped, resetting the MCU when using * an Arduino bootloader */ attribs.c_cflag &= ~HUPCL; if((status = serial_set_attrib(fd, &attribs)) < 0) { *detail = "can't prevent DTR from being dropped"; return status; } return 0; }