/* * Open the serial port. * Return -1 on error. */ int serial_open (const char *devname, int baud_rate, int timeout) { #if defined(__WIN32__) || defined(WIN32) DCB new_mode; COMMTIMEOUTS ctmo; #else struct termios new_mode; unsigned int ctl; int rv; #endif timeout_msec = timeout; #if defined(__WIN32__) || defined(WIN32) /* Check for the Windows device syntax and bend a DOS device * into that syntax to allow higher COM numbers than 9 */ if (devname[0] != '\\') { // Prepend device prefix: COM23 -> \\.\COM23 char *buf = alloca(5 + strlen(devname)); if (! buf) { fprintf (stderr, "%s: Out of memory\n", devname); return -1; } strcpy(buf, "\\\\.\\"); strcat(buf, devname); devname = buf; } /* Open port */ fd = CreateFile (devname, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); if (fd == INVALID_HANDLE_VALUE) { fprintf (stderr, "%s: Cannot open\n", devname); return -1; } /* Set serial attributes */ memset (&saved_mode, 0, sizeof(saved_mode)); if (! GetCommState (fd, &saved_mode)) { fprintf (stderr, "%s: Cannot get state\n", devname); return -1; } new_mode = saved_mode; new_mode.BaudRate = baud_rate; new_mode.ByteSize = 8; new_mode.StopBits = ONESTOPBIT; new_mode.Parity = 0; new_mode.fParity = FALSE; new_mode.fOutX = FALSE; new_mode.fInX = FALSE; new_mode.fOutxCtsFlow = FALSE; new_mode.fOutxDsrFlow = FALSE; new_mode.fRtsControl = RTS_CONTROL_ENABLE; new_mode.fNull = FALSE; new_mode.fAbortOnError = FALSE; new_mode.fBinary = TRUE; if (! SetCommState (fd, &new_mode)) { fprintf (stderr, "%s: Cannot set state\n", devname); return -1; } memset (&ctmo, 0, sizeof(ctmo)); ctmo.ReadIntervalTimeout = 0; ctmo.ReadTotalTimeoutMultiplier = 0; ctmo.ReadTotalTimeoutConstant = timeout_msec; if (! SetCommTimeouts (fd, &ctmo)) { fprintf (stderr, "%s: Cannot set timeouts\n", devname); return -1; } #else /* Encode baud rate. */ int baud_code = baud_encode (baud_rate); if (baud_code < 0) { fprintf (stderr, "%s: Bad baud rate %d\n", devname, baud_rate); return -1; } /* Open port */ fd = open (devname, O_RDWR | O_NOCTTY | O_NONBLOCK); if (fd < 0) { perror (devname); return -1; } /* Set serial attributes */ memset (&saved_mode, 0, sizeof(saved_mode)); tcgetattr (fd, &saved_mode); /* 8n1, ignore parity */ memset (&new_mode, 0, sizeof(new_mode)); new_mode.c_cflag = CS8 | CLOCAL | CREAD; new_mode.c_iflag = IGNBRK; new_mode.c_oflag = 0; new_mode.c_lflag = 0; new_mode.c_cc[VTIME] = 0; new_mode.c_cc[VMIN] = 1; cfsetispeed (&new_mode, baud_code); cfsetospeed (&new_mode, baud_code); tcflush (fd, TCIFLUSH); tcsetattr (fd, TCSANOW, &new_mode); /* Clear O_NONBLOCK flag. */ int flags = fcntl (fd, F_GETFL, 0); if (flags >= 0) fcntl (fd, F_SETFL, flags & ~O_NONBLOCK); rv = ioctl(fd, TIOCMGET, &ctl); if (rv < 0) { perror("ioctl(\"TIOCMGET\")"); return -1; } ctl &= ~(TIOCM_DTR | TIOCM_RTS); rv = ioctl(fd, TIOCMSET, &ctl); if (rv < 0) { perror("ioctl(\"TIOCMSET\")"); return -1; } usleep(250*1000); ctl |= (TIOCM_DTR | TIOCM_RTS); rv = ioctl(fd, TIOCMSET, &ctl); if (rv < 0) { perror("ioctl(\"TIOCMSET\")"); return -1; } usleep(50*1000); #endif return 0; }
/* * Open the serial port. * Return -1 on error. */ int serial_open(const char *devname, int baud_rate) { #if defined(__WIN32__) || defined(WIN32) DCB new_mode; COMMTIMEOUTS ctmo; #else struct termios new_mode; #endif #if defined(__WIN32__) || defined(WIN32) /* Open port */ fd = CreateFile(devname, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); if (fd == INVALID_HANDLE_VALUE) { fprintf(stderr, "%s: Cannot open\n", devname); return -1; } /* Set serial attributes */ memset(&saved_mode, 0, sizeof(saved_mode)); if (! GetCommState(fd, &saved_mode)) { fprintf(stderr, "%s: Cannot get state\n", devname); return -1; } new_mode = saved_mode; new_mode.BaudRate = baud_rate; new_mode.ByteSize = 8; new_mode.StopBits = ONESTOPBIT; new_mode.Parity = 0; new_mode.fParity = FALSE; new_mode.fOutX = FALSE; new_mode.fInX = FALSE; new_mode.fOutxCtsFlow = FALSE; new_mode.fOutxDsrFlow = FALSE; new_mode.fRtsControl = RTS_CONTROL_ENABLE; new_mode.fNull = FALSE; new_mode.fAbortOnError = FALSE; new_mode.fBinary = TRUE; if (! SetCommState(fd, &new_mode)) { fprintf(stderr, "%s: Cannot set state\n", devname); return -1; } memset(&ctmo, 0, sizeof(ctmo)); ctmo.ReadIntervalTimeout = 0; ctmo.ReadTotalTimeoutMultiplier = 0; ctmo.ReadTotalTimeoutConstant = 5000; if (! SetCommTimeouts(fd, &ctmo)) { fprintf(stderr, "%s: Cannot set timeouts\n", devname); return -1; } #else /* Encode baud rate. */ int baud_code = baud_encode(baud_rate); if (baud_code < 0) { fprintf(stderr, "%s: Bad baud rate %d\n", devname, baud_rate); return -1; } /* Open port */ fd = open(devname, O_RDWR | O_NOCTTY | O_NONBLOCK); if (fd < 0) { perror(devname); return -1; } /* Set serial attributes */ memset(&saved_mode, 0, sizeof(saved_mode)); tcgetattr(fd, &saved_mode); /* 8n1, ignore parity */ memset(&new_mode, 0, sizeof(new_mode)); new_mode.c_cflag = CS8 | CLOCAL | CREAD; new_mode.c_iflag = IGNBRK; new_mode.c_oflag = 0; new_mode.c_lflag = 0; new_mode.c_cc[VTIME] = 0; new_mode.c_cc[VMIN] = 1; cfsetispeed(&new_mode, baud_code); cfsetospeed(&new_mode, baud_code); tcflush(fd, TCIFLUSH); tcsetattr(fd, TCSANOW, &new_mode); /* Clear O_NONBLOCK flag. */ int flags = fcntl(fd, F_GETFL, 0); if (flags >= 0) fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); #endif return 0; }
/* * Check whether the given speed in bits per second * is supported by the system. * Return 0 when not supported. */ int serial_speed_valid (int bps) { return baud_encode (bps) > 0; }