00001 #include "SerialCommPort.h"
00002 #include <termios.h>
00003 #include <sys/ioctl.h>
00004 #include <errno.h>
00005 #ifdef __APPLE__
00006 # include <IOKit/serial/ioss.h>
00007 #endif
00008
00009 #ifdef __CYGWIN__
00010
00011
00012
00013
00014 void cfmakeraw(struct termios *termios_p) {
00015 termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
00016 |INLCR|IGNCR|ICRNL|IXON);
00017 termios_p->c_oflag &= ~OPOST;
00018 termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
00019 termios_p->c_cflag &= ~(CSIZE|PARENB);
00020 termios_p->c_cflag |= CS8;
00021 }
00022 #endif
00023
00024 using namespace std;
00025
00026 const char * const SerialCommPort::parityNames[] = { "EVEN", "ODD", "NONE", "" };
00027 INSTANTIATE_NAMEDENUMERATION_STATICS(SerialCommPort::parity_t);
00028
00029 const std::string SerialCommPort::autoRegisterSerialCommPort = CommPort::getRegistry().registerType<SerialCommPort>("SerialCommPort");
00030
00031 void SerialCommPort::setupSerial() {
00032 if(fd<0)
00033 return;
00034
00035
00036
00037
00038 struct termios theTermios;
00039 int ret = tcgetattr(fd, &theTermios);
00040 cfmakeraw(&theTermios);
00041
00042 #ifndef __APPLE__
00043
00044
00045 cfsetispeed(&theTermios, baudRate);
00046 cfsetospeed(&theTermios, baudRate);
00047 #endif
00048
00049
00050 theTermios.c_cflag |= CREAD | CLOCAL;
00051
00052
00053 switch (dataBits) {
00054 case 5: theTermios.c_cflag |= CS5; break;
00055 case 6: theTermios.c_cflag |= CS6; break;
00056 case 7: theTermios.c_cflag |= CS7; break;
00057 case 8: theTermios.c_cflag |= CS8; break;
00058 default: std::cerr << "SerialCommPort: bad DataBits value " << dataBits << std::endl;
00059 }
00060
00061
00062 if(stopBits==1)
00063 theTermios.c_cflag &= ~CSTOPB;
00064 else if(stopBits==2)
00065 theTermios.c_cflag |= CSTOPB;
00066 else
00067 std::cerr << "SerialCommPort: bad StopBits value " << stopBits << std::endl;
00068
00069
00070 switch(parity) {
00071 case EVEN:
00072 theTermios.c_cflag |= PARENB; theTermios.c_cflag &= ~PARODD; break;
00073 case ODD:
00074 theTermios.c_cflag |= PARENB; theTermios.c_cflag |= PARODD; break;
00075 case NONE:
00076 theTermios.c_cflag &= ~PARENB; break;
00077 }
00078
00079 theTermios.c_iflag &= ~(IXON | IXOFF);
00080 theTermios.c_cflag &= ~CRTSCTS;
00081
00082
00083 ret = tcsetattr(fd, TCSAFLUSH, &theTermios);
00084
00085 if (ret)
00086 dispError("tcsetattr(TCSAFLUSH)",ret,errno);
00087
00088 #ifdef __APPLE__
00089
00090 const int TGTBAUD = baudRate;
00091 ret = ioctl(fd, IOSSIOSPEED, &TGTBAUD);
00092 if (ret)
00093 dispError("ioctl(IOSSIOSPEED)",ret,errno);
00094 #endif
00095
00096
00097 int modem;
00098 ret = ioctl(fd, TIOCMGET, &modem);
00099 if (ret)
00100 dispError("ioctl(TIOCMGET)",ret,errno);
00101 modem |= TIOCM_DTR;
00102 ret = ioctl(fd, TIOCMSET, &modem);
00103 if (ret)
00104 dispError("ioctl(TIOCMSET)",ret,errno);
00105
00106 if(sttyConfig.size()>0) {
00107
00108 #ifdef __linux__
00109 std::string cmd="stty -F "+path+" "+sttyConfig;
00110 #else
00111 std::string cmd="stty -f "+path+" "+sttyConfig;
00112 #endif
00113 switch(::system(cmd.c_str())) {
00114 case 0:
00115 break;
00116 case -1:
00117 perror("Warning: SerialCommPort could not make system call to stty"); break;
00118 case 127:
00119 std::cerr << "Warning: SerialCommPort could not make system call to stty: no shell found" << std::endl; break;
00120 default:
00121 std::cerr << "Warning: SerialCommPort stty reported error on configuration string: " << sttyConfig << std::endl; break;
00122 }
00123 }
00124 }
00125
00126 void SerialCommPort::dispError(const char* where, int ret, int err) {
00127 std::cerr << where << " returned " << ret << " (errno " << err << ": " << strerror(err) << ")" << std::endl;
00128 }
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140