diff options
| author | Pavel Vymetálek <pavel@vym.cz> | 2026-11-02 09:26:46 +0100 |
|---|---|---|
| committer | Pavel Vymetálek <pavel@vym.cz> | 2026-11-02 09:26:46 +0100 |
| commit | 1ca5dc8496c67dcffd144b1071c5c045733a5461 (patch) | |
| tree | 520d82f2a6dd3e4121cc59cddc5159d64029929e /sercp.c | |
| parent | 283ddcd550593865e7e175b78372f4c3f56f80d7 (diff) | |
| download | sercp-pc-1ca5dc8496c67dcffd144b1071c5c045733a5461.tar.gz | |
Cleaner serial port initialization, detection of serial device disconnection
Diffstat (limited to 'sercp.c')
| -rw-r--r-- | sercp.c | 66 |
1 files changed, 41 insertions, 25 deletions
@@ -367,6 +367,14 @@ static void SignalHandler(int sig) { } //***************************************************************************** + +void SerialDeviceError(void) { + CloseSerialPort(); + fprintf(stderr, "\n[ERROR] The device %s has been disconnected or is invalid!\n", SERIALDEVICE); + exit(-1); +} + +//***************************************************************************** // void sleep_ms(int milliseconds) { @@ -583,6 +591,10 @@ uint8_t WaitReadAck(void) { memset(buf_ack, 0, 8); while (1) { result = poll (spolfd_serial, 1, 300); // 200ms timeout + if (spolfd_serial->revents & (POLLHUP | POLLERR | POLLNVAL)) { + SerialDeviceError(); + break; + } if (result == 0) { // nothing is comming continue; @@ -671,6 +683,11 @@ void sercpRecv(void) { while (is_continue) { #ifndef _WIN32 result = poll (spolfd_serial, 1, 200); // 200ms timeout + if (spolfd_serial->revents & (POLLHUP | POLLERR | POLLNVAL)) { + SerialDeviceError(); + break; + } + if (result == 0) { // nothing is comming continue; @@ -988,6 +1005,7 @@ int OpenUart() { return (0); #else struct termios oldtio, newtio; + speed_t serial_speed; /* open the device to be non-blocking (read will return immediatly) */ serial_fd = open(SERIALDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK); // | O_NDELAY if (serial_fd < 0) { @@ -1016,61 +1034,59 @@ int OpenUart() { tcgetattr(serial_fd, &oldtio); /* save current port settings */ memset(&newtio, 0, sizeof (newtio)); switch (baud_rate){ +#ifdef B921600 case 921600: - newtio.c_cflag = B921600; + serial_speed = B921600; break; +#endif +#ifdef B460800 case 460800: - newtio.c_cflag = B460800; + serial_speed = B460800; break; +#endif case 230400: - newtio.c_cflag = B230400; + serial_speed = B230400; break; case 115200: - newtio.c_cflag = B115200; + serial_speed = B115200; break; case 57600: - newtio.c_cflag = B57600; + serial_speed = B57600; break; case 38400: - newtio.c_cflag = B38400; + serial_speed = B38400; break; case 19200: - newtio.c_cflag = B19200; + serial_speed = B19200; break; case 9600: - newtio.c_cflag = B9600; + serial_speed = B9600; break; case 4800: - newtio.c_cflag = B4800; + serial_speed = B4800; break; case 2400: - newtio.c_cflag = B2400; + serial_speed = B2400; break; case 1200: - newtio.c_cflag = B1200; + serial_speed = B1200; break; default: baud_rate = 38400; - newtio.c_cflag = B38400; + serial_speed = B38400; break; } - cfsetospeed(&newtio, baud_rate); - cfsetispeed(&newtio, baud_rate); // set ispeed same as ospeed (see POSIX) + newtio.c_cflag = CS8 | CLOCAL | CREAD; + if (is_flow_control_hw) { #if defined (__APPLE__) || defined (BSD) - if (is_flow_control_none) { - printf("Sorry, flow control is not tested on this platform\n"); - newtio.c_cflag |= CS8 | CLOCAL | CREAD | HUPCL; - } else { - newtio.c_cflag |= CS8 | CLOCAL | CREAD | CCTS_OFLOW | CRTS_IFLOW | HUPCL; - } + newtio.c_cflag |= CCTS_OFLOW | CRTS_IFLOW; #else - if (is_flow_control_hw) { // standard CTS/RTS flow control for old .sercp protocol - newtio.c_cflag |= CS8 | CLOCAL | CREAD | CRTSCTS; - } else { - newtio.c_cflag |= CS8 | CLOCAL | CREAD; - } + newtio.c_cflag |= CRTSCTS; #endif + } + cfsetospeed(&newtio, serial_speed); + cfsetispeed(&newtio, serial_speed); // set ispeed same as ospeed (see POSIX) newtio.c_iflag &= ~(IXON | IXOFF | IXANY); newtio.c_oflag &= ~(OPOST); newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // raw input |
