aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Vymetálek <pavel@vym.cz>2026-11-02 09:26:46 +0100
committerPavel Vymetálek <pavel@vym.cz>2026-11-02 09:26:46 +0100
commit1ca5dc8496c67dcffd144b1071c5c045733a5461 (patch)
tree520d82f2a6dd3e4121cc59cddc5159d64029929e
parent283ddcd550593865e7e175b78372f4c3f56f80d7 (diff)
downloadsercp-pc-1ca5dc8496c67dcffd144b1071c5c045733a5461.tar.gz
Cleaner serial port initialization, detection of serial device disconnection
-rw-r--r--sercp.c66
1 files changed, 41 insertions, 25 deletions
diff --git a/sercp.c b/sercp.c
index 7acda1e..5eb087f 100644
--- a/sercp.c
+++ b/sercp.c
@@ -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