#ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include "serial.h" char *serial_names[10] = { "", "/dev/ttyS0", "/dev/ttyS1", "/dev/ttyS2", "/dev/ttyS3", "/dev/usb/ttyUSB0", "/dev/usb/ttyUSB1", "/dev/usb/ttyUSB2", "/dev/usb/ttyUSB3", NULL }; serial_t *serial_open(const char *devname) { serial_t *serport; serport = malloc(sizeof(serial_t)); serport->fd = open(devname, O_RDWR|O_NOCTTY|O_NONBLOCK /*|O_SYNC*/); if (serport->fd < 0) { free(serport); return NULL; } return serport; } void serial_setup(serial_t *serport) { struct termios *tio1, *tio2; int ret = 0; tio1 = &(serport->oldtio); tio2 = &(serport->newtio); if (tcgetattr(serport->fd, tio1)) ret = -1; memcpy(tio2, tio1, sizeof(struct termios)); cfmakeraw(tio2); cfsetospeed(tio2, B115200); cfsetispeed(tio2, B115200); #if 0 tio2->c_cflag |= CRTSCTS; #endif tio2->c_cflag |= CREAD|CLOCAL; tcflush(serport->fd, TCIOFLUSH); if (tcsetattr(serport->fd, TCSANOW, tio2)) ret = -1; #if 0 tcflow(serport->fd, TCOON); tcflow(serport->fd, TCION); #endif serport->err = ret; } void serial_close(serial_t *serport) { tcflush(serport->fd, TCIOFLUSH); tcsetattr(serport->fd, TCSANOW, &(serport->oldtio)); close(serport->fd); free(serport); } void serial_write(serial_t *serport, const char *buffer, size_t n) { int i; serport->err = write(serport->fd, buffer, n); tcdrain(serport->fd); } void serial_read(serial_t *serport, char *buffer, size_t n, int wait) { int pos = 0; int err = 0; struct timeval tv; fd_set set; if (wait) { FD_ZERO(&set); FD_SET(serport->fd, &set); tv.tv_sec = 0; tv.tv_usec = 250000; serport->err = select(serport->fd+1, &set, NULL, NULL, &tv); if (serport->err <= 0) return; } while(n--) { again: if (wait) { FD_ZERO(&set); FD_SET(serport->fd, &set); tv.tv_sec = 0; tv.tv_usec = 100000; serport->err = select(serport->fd+1, &set, NULL, NULL, &tv); if (serport->err <= 0) return; } serport->err = read(serport->fd, &buffer[pos++], 1); if (serport->err == 0) goto again; if (serport->err == -1) break; } if (serport->err != -1) serport->err = pos; } void serial_delay(int ms) { usleep(ms*1000); }