#include #include #include #include #include #include #include #include #include #include #include "log.h" #include "serial.h" struct serial_port { int fd; }; static speed_t baud(int speed) { if (speed == 230400) return B230400; else if (speed == 115200) return B115200; else if (speed == 57600) return B57600; else if (speed == 38400) return B38400; else if (speed == 19200) return B19200; else if (speed == 9600) return B9600; else if (speed == 4800) return B4800; else if (speed == 2400) return B2400; else if (speed == 1200) return B1200; else { loge("Error setting baud rate: %d not recognised.", speed); return B0; } } port_t * serial_open(const char *name, int speed) { port_t *pt = NULL; int fd; if ((fd = open(name, O_RDWR | O_NOCTTY))<0) { loge("Error: opening %s: %s", name, strerror(errno)); return NULL; } struct termios adtio; bzero(&adtio, sizeof(adtio)); tcgetattr(fd, &adtio); adtio.c_cflag = CS8 | CLOCAL | CREAD; adtio.c_iflag = IGNPAR | IGNBRK; adtio.c_oflag = 0; adtio.c_lflag = 0; // non-canon, no echo cfmakeraw(&adtio); adtio.c_cc[VTIME] = 0; adtio.c_cc[VMIN] = 1; cfsetispeed(&adtio, baud(speed)); cfsetospeed(&adtio, baud(speed)); tcsetattr(fd, TCSANOW, &adtio); pt = malloc(sizeof(port_t)); pt->fd = fd; return pt; } void serial_close(port_t * pt) { if (pt == NULL) return; if (pt->fd < 0) return; close(pt->fd); pt->fd = -1; return; } int serial_read(port_t * pt, unsigned char * buff, size_t len) { if (pt == NULL || pt->fd < 0) return -1; int ret = 0; int count = 0; unsigned char * p = buff; while (count < len) { ret = read(pt->fd, p, len-count); if (ret <= 0) return ret; p += ret; count += ret; } return count; } int serial_write(port_t * pt, unsigned char * buff, size_t len) { if (pt == NULL || pt->fd < 0) return -1; return write(pt->fd, buff, len); } int serial_break(port_t * pt, int set) { if (pt == NULL || pt->fd < 0) return -1; if (set) ioctl(pt->fd, TIOCSBRK, 0); else ioctl(pt->fd, TIOCCBRK, 0); return 0; }