gint setup_port(gint fd, gint baud) { #ifdef __WIN32__ win32_setup_serial_params(fd, baud, 8, NONE, 1); #else gint _baud = 0; /* Save serial port status */ tcgetattr(fd,&oldtio); flush_serial(fd, BOTH); memset(&newtio, 0, sizeof(newtio)); /* * BAUDRATE: Set bps rate. You could also use cfsetispeed and * cfsetospeed * CRTSCTS : output hardware flow control (only used if the cable has * all necessary lines. See sect. 7 of Serial-HOWTO) * CS8 : 8n1 (8bit,no parity,1 stopbit) * CLOCAL : local connection, no modem contol * CREAD : enable receiving characters */ /* Set baud (posix way) */ if (baud == 9600) _baud = B9600; else if (baud == 115200) _baud = B115200; else printf("INVALID BAUD RATE %i\n",baud); cfsetispeed(&newtio, _baud); cfsetospeed(&newtio, _baud); /* Mask and set to 8N1 mode... */ newtio.c_cflag &= ~( PARENB | CSTOPB | CSIZE); /* Set additional flags, note |= syntax.. */ /* Enable receiver, ignore modem ctrls lines, use 8 bits */ newtio.c_cflag |= CLOCAL | CREAD | CS8; /* RAW Input */ /* Ignore signals, enable canonical, etc */ newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /* Disable software flow control */ newtio.c_iflag &= ~(IXON | IXOFF ); /* Set raw output */ newtio.c_oflag &= ~OPOST; /* initialize all control characters default values can be found in /usr/include/termios.h, and are given in the comments, but we don't need them here * */ newtio.c_cc[VINTR] = 0; /* Ctrl-c */ newtio.c_cc[VQUIT] = 0; /* Ctrl-\ */ newtio.c_cc[VERASE] = 0; /* del */ newtio.c_cc[VKILL] = 0; /* @ */ newtio.c_cc[VEOF] = 0; /* Ctrl-d */ newtio.c_cc[VEOL] = 0; /* '\0' */ /* These are ZERO becasue we are using select() */ newtio.c_cc[VMIN] = 0; /* No min chars requirement */ newtio.c_cc[VTIME] = 0; /* 0ms timeout */ tcsetattr(fd,TCSANOW,&newtio); #endif return 0; }
/*! \brief setup_serial_params() is another wrapper that calls the appropriate calls to initialize the serial port to the proper speed, bits, flow, parity etc.. */ G_MODULE_EXPORT void setup_serial_params(void) { GMutex *serio_mutex = NULL; gchar * baud_str = NULL; Parity parity = NONE; gint baudrate = 0; gint bits = 0; gint stop = 0; Serial_Params *serial_params = NULL; #ifndef __WIN32__ speed_t baud; #endif serial_params = DATA_GET(global_data,"serial_params"); serio_mutex = DATA_GET(global_data,"serio_mutex"); baud_str = DATA_GET(global_data,"ecu_baud_str"); if (!parse_baud_str(baud_str,&baudrate,&bits,&parity,&stop)) MTXDBG(SERIAL_RD|SERIAL_WR|CRITICAL,_("ERROR! couldn't parse ecu_baud string %s\n"),baud_str); DATA_SET(global_data,"ecu_baud",GINT_TO_POINTER(baudrate)); if (serial_params->open == FALSE) return; if (DATA_GET(global_data,"network_mode")) { printf("network mode, exiting!\n"); return; } /*printf("setup_serial_params entered\n");*/ g_mutex_lock(serio_mutex); #ifdef __WIN32__ win32_setup_serial_params(serial_params->fd,baudrate,bits,parity,stop); #else /* Save serial port status */ tcgetattr(serial_params->fd,&serial_params->oldtio); g_mutex_unlock(serio_mutex); flush_serial(serial_params->fd, BOTH); g_mutex_lock(serio_mutex); /* Sets up serial port for the modes we want to use. * NOTE: Original serial tio params are stored and restored * in the open_serial() and close_serial() functions. */ /*clear struct for new settings*/ memset(&serial_params->newtio, 0, sizeof(serial_params->newtio)); /* * BAUDRATE: Set bps rate. You could also use cfsetispeed and * cfsetospeed * CRTSCTS : output hardware flow control (only used if the cable has * all necessary lines. See sect. 7 of Serial-HOWTO) * CS8 : 8n1 (8bit,no parity,1 stopbit) * CLOCAL : local connection, no modem contol * CREAD : enable receiving characters */ /* Set baud (posix way) */ switch (baudrate) { case 8192: baud = B38400; break; case 9600: baud = B9600; break; case 19200: baud = B19200; break; case 38400: baud = B38400; break; case 57600: baud = B57600; break; case 115200: baud = B115200; break; default: /* Assume 9600 */ baud = B9600; } cfsetispeed(&serial_params->newtio, baud); cfsetospeed(&serial_params->newtio, baud); /* Mask and set to 8N1 mode... */ /* Mask out HW flow control */ serial_params->newtio.c_cflag &= ~(CRTSCTS); /* Set additional flags, note |= syntax.. */ /* CLOCAL == Ignore modem control lines CREAD == Enable receiver */ serial_params->newtio.c_cflag |= CLOCAL | CREAD; /* Mask out Bit size */ serial_params->newtio.c_cflag &= ~(CSIZE); switch (bits) { case 8: serial_params->newtio.c_cflag |= CS8; break; case 7: serial_params->newtio.c_cflag |= CS7; break; case 6: serial_params->newtio.c_cflag |= CS6; break; case 5: serial_params->newtio.c_cflag |= CS5; break; } /* Mask out Parity Flags */ serial_params->newtio.c_cflag &= ~(PARENB | PARODD); switch (parity) { case ODD: serial_params->newtio.c_cflag |= (PARENB | PARODD); break; case EVEN: serial_params->newtio.c_cflag |= PARENB; break; case NONE: break; } /* Mask out Stip bit flags */ serial_params->newtio.c_cflag &= ~(CSTOPB); if (stop == 2) serial_params->newtio.c_cflag |= CSTOPB; /* 1 stop bit is default */ /* RAW Input */ /* Ignore signals, disable canonical, echo, etc */ /* serial_params->newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHONL | IEXTEN | ISIG); */ serial_params->newtio.c_lflag = 0; /* Disable software flow control */ serial_params->newtio.c_iflag &= ~(IXON | IXOFF | IXANY ); /* serial_params->newtio.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL ); */ serial_params->newtio.c_iflag = IGNBRK; /* Set raw output */ /* serial_params->newtio.c_oflag &= ~OPOST; */ serial_params->newtio.c_oflag = 0; /* initialize all control characters default values can be found in /usr/include/termios.h, and are given in the comments, but we don't need them here */ serial_params->newtio.c_cc[VINTR] = 0; /* Ctrl-c */ serial_params->newtio.c_cc[VQUIT] = 0; /* Ctrl-\ */ serial_params->newtio.c_cc[VERASE] = 0; /* del */ serial_params->newtio.c_cc[VKILL] = 0; /* @ */ serial_params->newtio.c_cc[VEOF] = 0; /* Ctrl-d */ serial_params->newtio.c_cc[VEOL] = 0; /* '\0' */ /* Fredcooke say vmin = 1 solves his hang on close issue with his broken FTDI driver, but that will break interrogation unless I completely transition to nonblocking IO */ serial_params->newtio.c_cc[VMIN] = 0; serial_params->newtio.c_cc[VTIME] = 1; /* 100ms timeout */ /* PIS Specific (odd baud rate) DISABLED */ /* if (ioctl(serial_params->fd, TIOCGSERIAL, &serial_params->oldctl) != 0) MTXDBG(SERIAL_RD|SERIAL_WR|CRITICAL, _("Error getting serial line information error %s\n"),strerror(errno)); else { MTXDBG(SERIAL_RD|SERIAL_WR, _("Get serial line info call OK\n")); // copy ioctl structure memcpy(&serial_params->newctl, &serial_params->oldctl, sizeof(serial_params->newctl)); // and if we are PIS 8192 make a custom divisor if (baudrate == 8192) { if (serial_params->newctl.baud_base < 115200) serial_params->newctl.baud_base = 115200; serial_params->newctl.custom_divisor = 14; serial_params->newctl.flags |= (ASYNC_SPD_MASK & ASYNC_SPD_CUST); if (ioctl(serial_params->fd, TIOCSSERIAL, &serial_params->newctl) != 0) MTXDBG(SERIAL_RD|SERIAL_WR|CRITICAL,_("Error setting ioctl\n")); else MTXDBG(SERIAL_RD|SERIAL_WR,_("Set ioctl OK\n")); } } */ tcsetattr(serial_params->fd, TCSANOW, &serial_params->newtio); #endif g_mutex_unlock(serio_mutex); flush_serial(serial_params->fd,BOTH); return; }