00001
00029 #include "sr_communications/serial_port/rs232.h"
00030
00032
00033 int Rs232::initCommunication(int baudrate, char *serialDevice, char *semFile)
00034 {
00036
00037 key_t semKey;
00038 struct termios newtio;
00039
00040 int error;
00041
00042 error = createKey(&semKey, semFile);
00043 if (error < 0) {
00044 ROS_ERROR("Error cretaing semaphore Key");
00045 return (-4);
00046 }
00047 error = getSemID(semKey, &_semID);
00048 if (error < 0) {
00049 ROS_ERROR("Error in getSemID. semKey = %x semFile = %s\n", semKey, semFile);
00050 return (-4);
00051 }
00052
00053 error = waitSem(_semID);
00054 if (error < 0) {
00055 ROS_ERROR("RS232.c - initCommunication: Error in waitSem\n\r");
00056 freeSem(_semID);
00057 rmSem(_semID);
00058 return (-4);
00059 }
00060
00061
00062
00063 _RSd = open(serialDevice, O_RDWR | O_NONBLOCK | O_NDELAY);
00064 if (_RSd < 0) {
00065 ROS_ERROR("Error opening serial device: %s", serialDevice);
00066 freeSem(_semID);
00067 rmSem(_semID);
00068 return (-2);
00069 }
00070
00071 bzero((void*) &newtio, sizeof(newtio));
00072 switch(baudrate) {
00073 case 4800:
00074 newtio.c_cflag = B4800 | CS8 | CLOCAL | CREAD;
00075 break;
00076 case 9600:
00077 newtio.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
00078 break;
00079 case 19200:
00080 newtio.c_cflag = B19200 | CS8 | CLOCAL | CREAD;
00081 break;
00082 case 38400:
00083 newtio.c_cflag = B38400 | CS8 | CLOCAL | CREAD;
00084 break;
00085 case 57600:
00086 newtio.c_cflag = B57600 | CS8 | CLOCAL | CREAD;
00087 break;
00088 case 115200:
00089 newtio.c_cflag = B115200 | CS8 | CLOCAL | CREAD;
00090 break;
00091 default:
00092 newtio.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
00093 }
00094 newtio.c_iflag = IGNPAR | ICRNL;
00095 newtio.c_oflag = 0;
00096
00097 newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
00098 newtio.c_cc[VINTR] = 0;
00099 newtio.c_cc[VQUIT] = 0;
00100 newtio.c_cc[VERASE] = 0;
00101 newtio.c_cc[VKILL] = 0;
00102 newtio.c_cc[VEOF] = 4;
00103 newtio.c_cc[VSWTC] = 0;
00104 newtio.c_cc[VSTART] = 0;
00105 newtio.c_cc[VSTOP] = 0;
00106 newtio.c_cc[VSUSP] = 0;
00107 newtio.c_cc[VEOL] = 0;
00108 newtio.c_cc[VREPRINT] = 0;
00109 newtio.c_cc[VDISCARD] = 0;
00110 newtio.c_cc[VWERASE] = 0;
00111 newtio.c_cc[VLNEXT] = 0;
00112 newtio.c_cc[VEOL2] = 0;
00113 newtio.c_cc[VTIME] = 0;
00114 newtio.c_cc[VMIN] = 0;
00115 tcflush(_RSd, TCIFLUSH);
00116 tcflush(_RSd, TCOFLUSH);
00117
00118 if (tcsetattr(_RSd, TCSANOW, &newtio)) {
00119 ROS_ERROR("Error configurating serial port dev = %s\n", serialDevice);
00120 freeSem(_semID);
00121 rmSem(_semID);
00122 return -1;
00123 }
00124
00125 if (tcflush(_RSd, TCIOFLUSH) < 0) {
00126 ROS_ERROR("Error flushing serial port dev = %s\n", serialDevice);
00127 freeSem(_semID);
00128 rmSem(_semID);
00129 return -1;
00130 }
00131
00132 freeSem(_semID);
00133
00134 return ERR_NOERR;
00135 }
00136
00138
00139 int Rs232::endCommunication()
00140 {
00141 waitSem(_semID);
00142 close(_RSd);
00143 freeSem(_semID);
00144
00145 return rmSem(_semID);
00146 }
00147
00149
00150 int Rs232::writeToRS232(char* command, int commandSize)
00151 {
00152 if (waitSem(_semID) < ERR_NOERR) {
00153 ROS_ERROR("Error when waiting the semaphore\n\r");
00154 freeSem(_semID);
00155 return ERR_SEM;
00156 }
00157
00158 if (write(_RSd, command, commandSize) <= ERR_NOERR) {
00159 ROS_ERROR("Error when writing in the serial port file descriptor\n\r");
00160 freeSem(_semID);
00161 return ERR_WRI;
00162 }
00163
00164 freeSem(_semID);
00165 return ERR_NOERR;
00166 }
00167
00169
00170 int Rs232::readFromRS232(char * buff)
00171 {
00172 int i = 0;
00173
00174 int readResult;
00175 int status = 1;
00176 int bytes = 0;
00177
00178 struct timeval before, now;
00179
00180 if (waitSem(_semID) < ERR_NOERR) {
00181 ROS_ERROR("Error when waiting the semaphore\n\r");
00182 freeSem(_semID);
00183 return ERR_SEM;
00184 }
00185
00186 gettimeofday(&before, 0);
00187 do {
00188
00189 ioctl(_RSd, FIONREAD, &bytes);
00190 if (bytes > 0) {
00191 readResult = read(_RSd, &buff[i], 1);
00192 if (readResult < 0) {
00193 ROS_ERROR("Reading Error");
00194 freeSem(_semID);
00195 return (ERR_READ);
00196 }
00197 else {
00198 i += readResult;
00199 }
00200
00201 if (i > 1) {
00202 if ((buff[i - 2] == '\n') && (buff[i - 1] == '\n')) {
00203 status = 0;
00204 }
00205 }
00206 }
00207
00208 gettimeofday(&now, 0);
00209 if (SP_READ_TIMEOUT < timeDifferenceMsec(&before, &now)) {
00210 freeSem(_semID);
00211 return (ERR_TIMEOUT);
00212 }
00213
00214 usleep(1);
00215 }
00216 while(status);
00217
00218 freeSem(_semID);
00219
00220 return (status);
00221 }
00222
00224
00225 int Rs232::askToRS232(char *command, int commandSize, char *response)
00226 {
00227 int i = 0;
00228
00229 int readResult;
00230 int status = 1;
00231 int bytes = 0;
00232
00233 struct timeval before, now;
00234
00235 if (waitSem(_semID) < ERR_NOERR) {
00236 ROS_ERROR("Error when waiting the semaphore\n\r");
00237 freeSem(_semID);
00238 return ERR_SEM;
00239 }
00240
00241
00242 if (write(_RSd, command, commandSize) <= ERR_NOERR) {
00243 ROS_ERROR("Error when asking (writing) to the serial port file descriptor\n\r");
00244 freeSem(_semID);
00245 return ERR_WRI;
00246 }
00247
00248
00249 gettimeofday(&before, 0);
00250 do {
00251
00252 ioctl(_RSd, FIONREAD, &bytes);
00253 if (bytes > 0) {
00254 readResult = read(_RSd, &response[i], 1);
00255 if (readResult < 0) {
00256 ROS_ERROR("Reading Error");
00257 freeSem(_semID);
00258 return (ERR_READ);
00259 }
00260 else {
00261 i += readResult;
00262 }
00263
00264 if (i > 1) {
00265 if ((response[i - 2] == '\n') && (response[i - 1] == '\n')) {
00266 status = ERR_NOERR;
00267 }
00268 }
00269 }
00270
00271 gettimeofday(&now, 0);
00272 if (SP_READ_TIMEOUT < timeDifferenceMsec(&before, &now)) {
00273 freeSem(_semID);
00274 ROS_ERROR("Timeout Error. Error when asking to the serial port file descriptor\n\r");
00275 ROS_ERROR("status : %d\n", status);
00276 return (ERR_TIMEOUT);
00277 }
00278 usleep(100);
00279 }
00280 while(status);
00281
00282 freeSem(_semID);
00283
00284 return (status);
00285 }
00286
00288
00290
00291 int Rs232::readSerial(char *response, int responseSize)
00292 {
00293 int i = 0;
00294 int readResult;
00295 int status = 1;
00296 int bytes = 0;
00297
00298 struct timeval before, now;
00299
00300 gettimeofday(&before, 0);
00301 do {
00302
00303 ioctl(_RSd, FIONREAD, &bytes);
00304 if (bytes > 0) {
00305 readResult = read(_RSd, &response[i], responseSize);
00306
00307 if (readResult < 0) {
00308 ROS_ERROR("Reading Error: %d.", readResult);
00309 freeSem(_semID);
00310 return (ERR_READ);
00311 }
00312 else if (readResult == 0) {
00313
00314 ROS_ERROR("Reading Error: EOF reached");
00315 freeSem(_semID);
00316 return (ERR_READ);
00317 }
00318 else {
00319 i += readResult;
00320 }
00321
00322
00323 if (i == responseSize) {
00324 status = 0;
00325 }
00326 }
00327
00328 gettimeofday(&now, 0);
00329 if (SPLT_READ_TIMEOUT < timeDifferenceMsec(&before, &now)) {
00330 freeSem(_semID);
00331 ROS_ERROR("Timeout ERROR while reading");
00332 return (ERR_TIMEOUT);
00333 }
00334
00335
00336 usleep(500);
00337
00338 }
00339 while(status);
00340
00341
00342 return (i);
00343 }
00344
00346
00347 int Rs232::askToSerial(char *command, int commandSize, char *response, int responseSize)
00348 {
00349 int i = 0;
00350 int readResult;
00351 int status = 1;
00352 int bytes = 0;
00353
00354 struct timeval before, now;
00355
00356
00357 if (write(_RSd, command, commandSize) <= ERR_NOERR) {
00358 ROS_ERROR("Error when asking (writing) to the serial port file descriptor\n\r");
00359 freeSem(_semID);
00360 return ERR_WRI;
00361 }
00362
00363
00364 gettimeofday(&before, 0);
00365 do {
00366
00367 ioctl(_RSd, FIONREAD, &bytes);
00368 if (bytes > 0) {
00369 readResult = read(_RSd, &response[i], responseSize);
00370
00371 if (readResult < 0) {
00372 ROS_ERROR("Reading Error: %d.", readResult);
00373 freeSem(_semID);
00374 return (ERR_READ);
00375 }
00376 else if (readResult == 0) {
00377
00378 ROS_ERROR("Reading Error: EOF reached");
00379 freeSem(_semID);
00380 return (ERR_READ);
00381 }
00382 else {
00383 i += readResult;
00384 }
00385
00386
00387 if (i == responseSize) {
00388 status = 0;
00389 }
00390 }
00391
00392 gettimeofday(&now, 0);
00393 if (SPLT_READ_TIMEOUT < timeDifferenceMsec(&before, &now)) {
00394 freeSem(_semID);
00395 ROS_ERROR("Timeout ERROR while reading (asking)");
00396 return (ERR_TIMEOUT);
00397 }
00398
00399
00400 usleep(500);
00401
00402 }
00403 while(status);
00404
00405 return (i);
00406 }
00407
00409
00410 long int Rs232::timeDifferenceMsec(struct timeval *before, struct timeval *after)
00411 {
00413 return ((after->tv_sec - before->tv_sec) * 1000 + (after->tv_usec - before->tv_usec) / 1000);
00414 }
00415