X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=hardware%2Fcommon%2Fserial.c;h=0b9b1c8c390917bf7be44b13beaaf1467da49cc3;hb=1fdb75e14528abd62ebe727537512c741a5759da;hp=9ab3169ce03af451a9d3474530eda5fa8ac36895;hpb=926b866cb624cebf2efca098088dba11afa8ae96;p=libsigrok.git diff --git a/hardware/common/serial.c b/hardware/common/serial.c index 9ab3169c..0b9b1c8c 100644 --- a/hardware/common/serial.c +++ b/hardware/common/serial.c @@ -60,12 +60,11 @@ GSList *list_serial_ports(void) ports = NULL; for (i = 0; serial_port_glob[i]; i++) { - if (!glob(serial_port_glob[i], 0, NULL, &g)) { - for (j = 0; j < g.gl_pathc; j++) - ports = g_slist_append(ports, - strdup(g.gl_pathv[j])); - globfree(&g); - } + if (glob(serial_port_glob[i], 0, NULL, &g)) + continue; + for (j = 0; j < g.gl_pathc; j++) + ports = g_slist_append(ports, strdup(g.gl_pathv[j])); + globfree(&g); } return ports; @@ -96,6 +95,24 @@ int serial_close(int fd) #endif } +/* + * Flush serial port buffers (if any). + * Returns 0 upon success, -1 upon failure. + */ +int serial_flush(int fd) +{ +#ifdef _WIN32 + /* Returns non-zero upon success, 0 upon failure. */ + if (PurgeComm(hdl, PURGE_RXCLEAR | PURGE_TXCLEAR) == 0) + return -1; + else + return 0; +#else + /* Returns 0 upon success, -1 upon failure. */ + return tcflush(fd, TCIOFLUSH); +#endif +} + void *serial_backup_params(int fd) { #ifdef _WIN32 @@ -119,7 +136,10 @@ void serial_restore_params(int fd, void *backup) #endif } -/* flowcontrol 1 = rts/cts 2 = xon/xoff */ +/* + * flowcontrol 1 = rts/cts 2 = xon/xoff + * parity 0 = none, 1 = even, 2 = odd + */ int serial_set_params(int fd, int speed, int bits, int parity, int stopbits, int flowcontrol) { @@ -132,6 +152,7 @@ int serial_set_params(int fd, int speed, int bits, int parity, int stopbits, /* TODO: Rename 'speed' to 'baudrate'. */ switch(speed) { + /* TODO: Support for higher baud rates. */ case 115200: dcb.BaudRate = CBR_115200; break; @@ -160,21 +181,82 @@ int serial_set_params(int fd, int speed, int bits, int parity, int stopbits, } #else struct termios term; + speed_t baud; - /* Only supporting what we need really, currently the OLS driver. */ - if (speed != 115200 || bits != 8 || parity != 0 || stopbits != 1 - || flowcontrol != 2) + switch (speed) { + case 9600: + baud = B9600; + break; + case 38400: + baud = B38400; + break; + case 57600: + baud = B57600; + break; + case 115200: + baud = B115200; + break; + case 460800: + baud = B460800; + break; + default: return SIGROK_ERR; + } if (tcgetattr(fd, &term) < 0) return SIGROK_ERR; - if (cfsetispeed(&term, B115200) < 0) + if (cfsetispeed(&term, baud) < 0) return SIGROK_ERR; + term.c_cflag &= ~CSIZE; - term.c_cflag |= CS8; + switch (bits) { + case 8: + term.c_cflag |= CS8; + break; + case 7: + term.c_cflag |= CS7; + break; + default: + return SIGROK_ERR; + } + term.c_cflag &= ~CSTOPB; - term.c_cflag |= IXON | IXOFF; - term.c_iflag |= IGNPAR; + switch (stopbits) { + case 1: + break; + case 2: + term.c_cflag |= CSTOPB; + default: + return SIGROK_ERR; + } + + term.c_cflag &= ~(IXON | IXOFF | CRTSCTS); + switch (flowcontrol) { + case 2: + term.c_cflag |= IXON | IXOFF; + break; + case 1: + term.c_cflag |= CRTSCTS; + default: + return SIGROK_ERR; + } + + term.c_iflag &= ~IGNPAR; + term.c_cflag &= ~(PARODD | PARENB); + switch (parity) { + case 0: + term.c_iflag |= IGNPAR; + break; + case 1: + term.c_cflag |= PARENB; + break; + case 2: + term.c_cflag |= PARENB | PARODD; + break; + default: + return SIGROK_ERR; + } + if (tcsetattr(fd, TCSADRAIN, &term) < 0) return SIGROK_ERR; #endif