SerialCommPort.cc
Go to the documentation of this file.00001 #include "SerialCommPort.h"
00002 #include <sys/ioctl.h>
00003 #include <errno.h>
00004 #ifdef __APPLE__
00005 # include <IOKit/serial/ioss.h>
00006 #endif
00007 #ifdef __linux__
00008 # include <linux/serial.h>
00009 #endif
00010
00011 #ifdef __CYGWIN__
00012
00013
00014
00015
00016 void cfmakeraw(struct termios *termios_p) {
00017 termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
00018 |INLCR|IGNCR|ICRNL|IXON);
00019 termios_p->c_oflag &= ~OPOST;
00020 termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
00021 termios_p->c_cflag &= ~(CSIZE|PARENB);
00022 termios_p->c_cflag |= CS8;
00023 }
00024 #endif
00025
00026 using namespace std;
00027
00028 const char * const SerialCommPort::parityNames[] = { "EVEN", "ODD", "NONE", NULL };
00029 INSTANTIATE_NAMEDENUMERATION_STATICS(SerialCommPort::parity_t);
00030
00031 std::map<int,speed_t> SerialCommPort::bauds;
00032
00033 const std::string SerialCommPort::autoRegisterSerialCommPort = CommPort::getRegistry().registerType<SerialCommPort>("SerialCommPort");
00034
00035 void SerialCommPort::setupSerial() {
00036 if(fd<0)
00037 return;
00038
00039
00040
00041
00042 struct termios theTermios;
00043 int ret = tcgetattr(fd, &theTermios);
00044 cfmakeraw(&theTermios);
00045
00046
00047
00048 #ifndef __APPLE__
00049 std::map<int,speed_t>::const_iterator baudIt = bauds.find(baudRate);
00050 # ifdef __linux__
00051
00052 const speed_t TGTBAUD = baudIt==bauds.end() ? B38400 : baudIt->second;
00053 # else
00054
00055
00056 const speed_t TGTBAUD = baudIt==bauds.end() ? baudRate : baudIt->second;
00057 # endif
00058 ret = cfsetispeed(&theTermios, TGTBAUD);
00059 if(ret)
00060 dispError("cfsetispeed",ret,errno);
00061 ret = cfsetospeed(&theTermios, TGTBAUD);
00062 if(ret)
00063 dispError("cfsetospeed",ret,errno);
00064 #endif
00065
00066
00067 theTermios.c_cflag |= CREAD | CLOCAL;
00068
00069
00070 switch (dataBits) {
00071 case 5: theTermios.c_cflag |= CS5; break;
00072 case 6: theTermios.c_cflag |= CS6; break;
00073 case 7: theTermios.c_cflag |= CS7; break;
00074 case 8: theTermios.c_cflag |= CS8; break;
00075 default: std::cerr << "SerialCommPort: bad DataBits value " << dataBits << std::endl;
00076 }
00077
00078
00079 if(stopBits==1u)
00080 theTermios.c_cflag &= ~CSTOPB;
00081 else if(stopBits==2u)
00082 theTermios.c_cflag |= CSTOPB;
00083 else
00084 std::cerr << "SerialCommPort: bad StopBits value " << stopBits << std::endl;
00085
00086
00087 switch(parity) {
00088 case EVEN:
00089 theTermios.c_cflag |= PARENB; theTermios.c_cflag &= ~PARODD; break;
00090 case ODD:
00091 theTermios.c_cflag |= PARENB; theTermios.c_cflag |= PARODD; break;
00092 case NONE:
00093 theTermios.c_cflag &= ~PARENB; break;
00094 }
00095
00096 theTermios.c_iflag &= ~(IXON | IXOFF);
00097 theTermios.c_cflag &= ~CRTSCTS;
00098
00099
00100 ret = tcsetattr(fd, TCSAFLUSH, &theTermios);
00101
00102 if (ret)
00103 dispError("tcsetattr(TCSAFLUSH)",ret,errno);
00104
00105 #ifdef __APPLE__
00106
00107 const int TGTBAUD = baudRate;
00108 ret = ioctl(fd, IOSSIOSPEED, &TGTBAUD);
00109 if (ret)
00110 dispError("ioctl(IOSSIOSPEED)",ret,errno);
00111 #endif
00112
00113 #ifdef __linux__
00114 if(baudIt==bauds.end()) {
00115 serial_struct sserial;
00116 ret = ioctl(fd, TIOCGSERIAL, &sserial);
00117 if(ret)
00118 dispError("ioctl(TIOCGSERIAL)",ret,errno);
00119 else {
00120
00121 if(baudIt==bauds.end())
00122 sserial.flags |= ASYNC_SPD_CUST;
00123 else
00124 sserial.flags &= ~ASYNC_SPD_MASK;
00125
00126 sserial.flags |= ASYNC_LOW_LATENCY;
00127 sserial.custom_divisor = (int)(sserial.baud_base / (float)baudRate + .5);
00128 ret = ioctl(fd, TIOCSSERIAL, &sserial);
00129 if(ret)
00130 dispError("ioctl(TIOCSSERIAL)",ret,errno);
00131 }
00132 }
00133 #endif
00134
00135
00136 int modem;
00137 ret = ioctl(fd, TIOCMGET, &modem);
00138 if (ret!=0) {
00139
00140
00141 } else {
00142 modem |= TIOCM_DTR;
00143 ret = ioctl(fd, TIOCMSET, &modem);
00144 if (ret)
00145 dispError("ioctl(TIOCMSET)",ret,errno);
00146 }
00147
00148
00149
00150 if(sttyConfig.size()>0) {
00151
00152 #ifdef __linux__
00153 std::string cmd="stty -F "+path+" "+sttyConfig;
00154 #else
00155 std::string cmd="stty -f "+path+" "+sttyConfig;
00156 #endif
00157 switch(::system(cmd.c_str())) {
00158 case 0:
00159 break;
00160 case -1:
00161 perror("Warning: SerialCommPort could not make system call to stty"); break;
00162 case 127:
00163 std::cerr << "Warning: SerialCommPort could not make system call to stty: no shell found" << std::endl; break;
00164 default:
00165 std::cerr << "Warning: SerialCommPort stty reported error on configuration string: " << sttyConfig << std::endl; break;
00166 }
00167 }
00168 }
00169
00170 void SerialCommPort::dispError(const char* where, int ret, int err) {
00171 std::cerr << where << " returned " << ret << " (errno " << err << ": " << strerror(err) << ")" << std::endl;
00172 }
00173
00174 void SerialCommPort::initBauds() {
00175 #ifdef B0
00176 bauds[0]=B0;
00177 #endif
00178 #ifdef B50
00179 bauds[50]=B50;
00180 #endif
00181 #ifdef B75
00182 bauds[75]=B75;
00183 #endif
00184 #ifdef B110
00185 bauds[110]=B110;
00186 #endif
00187 #ifdef B134
00188 bauds[134]=B134;
00189 #endif
00190 #ifdef B150
00191 bauds[150]=B150;
00192 #endif
00193 #ifdef B200
00194 bauds[200]=B200;
00195 #endif
00196 #ifdef B300
00197 bauds[300]=B300;
00198 #endif
00199 #ifdef B600
00200 bauds[600]=B600;
00201 #endif
00202 #ifdef B1200
00203 bauds[1200]=B1200;
00204 #endif
00205 #ifdef B1200
00206 bauds[1200]=B1200;
00207 #endif
00208 #ifdef B1800
00209 bauds[1800]=B1800;
00210 #endif
00211 #ifdef B2400
00212 bauds[2400]=B2400;
00213 #endif
00214 #ifdef B4800
00215 bauds[4800]=B4800;
00216 #endif
00217 #ifdef B9600
00218 bauds[9600]=B9600;
00219 #endif
00220 #ifdef B19200
00221 bauds[19200]=B19200;
00222 #endif
00223 #ifdef B38400
00224 bauds[38400]=B38400;
00225 #endif
00226 #ifdef B57600
00227 bauds[57600]=B57600;
00228 #endif
00229 #ifdef B76800
00230 bauds[76800]=B76800;
00231 #endif
00232 #ifdef B115200
00233 bauds[115200]=B115200;
00234 #endif
00235 #ifdef B153600
00236 bauds[153600]=B153600;
00237 #endif
00238 #ifdef B230400
00239 bauds[230400]=B230400;
00240 #endif
00241 #ifdef B307200
00242 bauds[307200]=B307200;
00243 #endif
00244 #ifdef B460800
00245 bauds[460800]=B460800;
00246 #endif
00247 #ifdef B500000
00248 bauds[500000]=B500000;
00249 #endif
00250 #ifdef B576000
00251 bauds[576000]=B576000;
00252 #endif
00253 #ifdef B921600
00254 bauds[921600]=B921600;
00255 #endif
00256 #ifdef B1000000
00257 bauds[1000000]=B1000000;
00258 #endif
00259 #ifdef B1152000
00260 bauds[1152000]=B1152000;
00261 #endif
00262 #ifdef B1500000
00263 bauds[1500000]=B1500000;
00264 #endif
00265 #ifdef B2000000
00266 bauds[2000000]=B2000000;
00267 #endif
00268 #ifdef B2500000
00269 bauds[2500000]=B2500000;
00270 #endif
00271 #ifdef B3000000
00272 bauds[3000000]=B3000000;
00273 #endif
00274 #ifdef B3500000
00275 bauds[3500000]=B3500000;
00276 #endif
00277 #ifdef B4000000
00278 bauds[4000000]=B4000000;
00279 #endif
00280 }
00281
00282
00283
00284
00285