/home/fwph/code/wurde/modules/ptu/linuxser.cpp

Go to the documentation of this file.
00001 /*************************************************************************
00002 *****    MACHINE-DEPENDENT SERIAL SUPPORT INCLUDE FILE WSERIAL.C     *****
00003 *****                             (LINUX)                            *****
00004 *****                                                                *****
00005 *****               (C)2000, Directed Perception, Inc.               *****
00006 *****                     All Rights Reserved.                       *****
00007 *****                                                                *****
00008 *****   Licensed users may freely distribute compiled code including *****
00009 *****   this code and data. Source data and code may NOT be          *****
00010 *****   distributed without the prior written consent from           *****
00011 *****   Directed Perception, Inc.                                    *****
00012 *****         Directed Perception, Inc. reserves the right to make   *****
00013 *****   changes without further notice to any content herein to      *****
00014 *****   improve reliability, function or design. Directed Perception *****
00015 *****   shall not assume any liability arising from the application  *****
00016 *****   or use of this code, data or function.                       *****
00017 *****                                                                *****
00018 **************************************************************************
00019 
00020 CHANGE HISTORY:
00021    4/21/99: v1.1.   Added CLOCAL to info.c_cflag 
00022    1/21/98: v1.0d.  First release of Linux serial port drivers developed
00023                     and tested under RedHat Linux v5.1.
00024 
00025 **************************************************************************/
00026 
00027 #include <termios.h>
00028 #include <stdio.h>
00029 #include <fcntl.h>
00030 #include <sys/types.h>
00031 #include <sys/time.h>
00032 #include <string.h>
00033 #include <unistd.h>
00034 #include "linuxser.h"
00035 
00036 #define DEBUG 0
00037 
00038 //***************************************************************
00039 //*****                LOCAL STATIC STATE                   *****
00040 //***************************************************************
00041 static int err;
00042 
00043 static unsigned char peeked_char, peeked_char_avail = FALSE;
00044 
00045 //********************************************************************
00046 //*****               PORTED ROUTINES                            *****
00047 //********************************************************************
00048 
00049 portstream_fd openserial(char *portname)
00050 {
00051         int pt_fd;
00052         struct termios info;
00053 
00054         fprintf(stderr, "openserial: opening device %s\n", portname);
00055         if ((pt_fd=open(portname, O_RDWR|O_NONBLOCK)) < 0)
00056         {
00057                 perror("Error opening serial port");
00058                 return PORT_NOT_OPENED;
00059         }
00060 
00061         if (tcgetattr(pt_fd, &info) < 0)
00062         {
00063                 perror("Error using TCGETS in ioctl.");
00064                 close(pt_fd);
00065                 return PORT_NOT_OPENED;
00066         }
00067 
00068         /* restore old values to unhang the PTU, if hung */
00069         info.c_iflag=1280;
00070         info.c_oflag=5;
00071         info.c_oflag=5;
00072         info.c_cflag=3261;
00073         info.c_lflag=35387;
00074 
00075         if (tcsetattr(pt_fd, TCSANOW, &info) < 0)
00076         {
00077                 perror("Error using TCSETS in ioctl.");
00078                 close(pt_fd);
00079                 return PORT_NOT_OPENED;
00080         }
00081         close(pt_fd);
00082 
00083         if ((pt_fd=open(portname, O_RDWR)) < 0)
00084         {
00085                 perror("Error opening serial port");
00086                 return PORT_NOT_OPENED;
00087         }
00088 
00089         if (tcgetattr(pt_fd, &info) < 0)
00090         {
00091                 perror("Error using TCGETS in ioctl");
00092                 close(pt_fd);
00093                 return PORT_NOT_OPENED;
00094         }
00095 
00096         info.c_iflag = IGNBRK | IGNPAR;
00097         info.c_iflag &= ~(INLCR | ICRNL | IUCLC | ISTRIP | IXON | BRKINT);
00098         info.c_oflag &= ~OPOST;
00099         info.c_lflag &= ~(ICANON | ISIG | ECHO);
00100         info.c_cflag = B9600 | CS8 | CREAD | CLOCAL;
00101 
00102         if (tcsetattr(pt_fd, TCSANOW, &info) < 0)
00103         {
00104                 perror("Error using TCSETS in ioctl");
00105                 close(pt_fd);
00106                 return PORT_NOT_OPENED;
00107         }
00108 
00109         return pt_fd;
00110 }
00111 
00112 char closeserial(portstream_fd pt_fd)
00113 {   
00114         if (pt_fd != PORT_NOT_OPENED) {                         
00115                 close(pt_fd);
00116         }
00117         return TRUE;
00118 }
00119 
00120 /* returns TRUE if all is OK */
00121 char SerialBytesOut(portstream_fd pt_fd, unsigned char *buffer,
00122                             int nBytes)
00123 {
00124         register int nout;
00125         nout = write(pt_fd, buffer, nBytes);      /* command byte(s) */
00126 
00127         if (nout == nBytes)
00128                 return TRUE;
00129         else
00130                 return FALSE;
00131 }
00132 
00133 /* returns TRUE if executed correctly */
00134 char SerialBytesIn (portstream_fd pt_fd, unsigned char *buffer,
00135                             unsigned int nBytes, long timeoutVal)
00136 {
00137         fd_set         readfds; /* list of fds for select to listen to */
00138         register int   i,noconn=0,n,bytesrec=0;
00139         char           inchars[256],*vptr;
00140         struct timeval timeout={((timeoutVal > 0) ? timeoutVal : 10),0};
00141 
00142         if (pt_fd == PORT_NOT_OPENED) 
00143            return FALSE;
00144 
00145         vptr=(char *) buffer;
00146 
00147         FD_ZERO(&readfds); FD_SET(pt_fd,&readfds);
00148         /* put only <fd> into the list of file descriptors we want to listen to */
00149 
00150         for (i=0; (i<nBytes) && (noconn==0); i++) {
00151                 if (select(FD_SETSIZE,&readfds,(fd_set *)NULL,
00152                         (fd_set *)NULL,&timeout)>0) {
00153                                 n=read(pt_fd,inchars,1); /* read one character at a time */
00154                                 *vptr++ = inchars[0];
00155                                 bytesrec++;
00156                 } else {  /* if timeout occurred */
00157                         noconn=1;
00158                         fprintf(stderr,"SerialBytesIn: timeout during data receive\n");
00159                 }
00160         }
00161 #if DEBUG
00162         if (bytesrec == 1)
00163                 fprintf(stderr,"SerialBytesIn: received <%u>\n", *buffer);
00164         else
00165                 fprintf(stderr,"SerialBytesIn: received <%s> %d bytes - req. %d bytes\n", buffer, bytesrec, nBytes);
00166 #endif
00167         if (bytesrec == nBytes) {
00168                 return TRUE;
00169         } else {
00170                 return FALSE;
00171         }
00172 }
00173 
00174 // returns TRUE if BYTE available to peek at; otherwise, FALSE
00175 char PeekByte(portstream_fd portstream, unsigned char *peekedByte) 
00176 {  
00177    return FALSE;
00178 }
00179 
00180 
00181 char FlushInputBuffer(portstream_fd pt_fd) {  
00182         return TRUE;
00183 }
00184 
00185 
00186 /* send a string to the PTU on file descriptor <fd> */
00187 char SerialStringOut(portstream_fd pt_fd, unsigned char *buffer)
00188 {
00189         char s[256];
00190         register int len,nout;
00191 
00192         sprintf(s,"%s",buffer);  /* make a proper string out of buffer, just in case
00193                                                                 buffer doesn't end with a '\0' -- this is
00194                                                                 unnecessary if the '\0' is ensured to be there
00195                                                                 already */
00196         len=strlen(s);
00197 
00198         nout = write(pt_fd,s,len);       /* switch code and message */
00199         nout+= write(pt_fd," ",1);       /* terminator */
00200 
00201         return TRUE;
00202 }
00203 
00204 // if string successfully read, returns TRUE; otherwise, the negative error
00205 // code. The number of characters read is returned in charsRead.
00206 char ReadSerialLine(portstream_fd pt_fd, unsigned char *strbuffer, 
00207                         long timeoutVal, int *charsRead)
00208 {
00209         char           out[2],*c,*sb;
00210         fd_set         readfds;
00211         int            n;
00212         unsigned char  done=FALSE;
00213         struct timeval timeout={((timeoutVal > 0) ? timeoutVal : 10),0};
00214 
00215         //???
00216     sprintf((char*)strbuffer,"");
00217 
00218         FD_ZERO(&readfds); FD_SET(pt_fd,&readfds);
00219         c=out;
00220         sb=(char *)strbuffer;
00221 
00222         while (!done && select(FD_SETSIZE,&readfds,(fd_set *)NULL,
00223                          (fd_set *)NULL,&timeout)>0) {
00224                 n=read(pt_fd,c,1);
00225                 if (*c == '\n') {  /* end of message.  Terminate string and loop */
00226                         *sb = '\0';
00227                         done=TRUE;
00228                 } else if (*c == '\r') {
00229                         /* do nothing, if controller sends \r\n */
00230                 } else {
00231                         /* put current character into return string */
00232                         *sb++ = *c;
00233                 }
00234                 *charsRead += n;
00235         }
00236 
00237         if (!done) {  /* timeout occurred */
00238                 return(TIMEOUT_CHAR_READ);
00239         }
00240 
00241         if (strbuffer[0] == '!' || strbuffer[1] == '!') {
00242                 /* if message from PTU begins with a !, then it is an error.  If
00243                  * echoing mode is on, then the ! won't be the first character so this
00244                  * may need to be changed.  I never use echoing though... */
00245 
00246                 fprintf(stderr, "ReadSerialLine: Error <%s>\n", strbuffer);
00247                 return(FALSE);
00248         } else {
00249 #if DEBUG
00250                 fprintf(stderr, "ReadSerialLine: got string <%s>\n", strbuffer);
00251 #endif
00252                 return(TRUE);
00253         }
00254 }
00255 
00256 void do_delay(long millisec)
00257 {
00258         struct timeval tv;
00259         double elapsedTime, startTime;
00260     double delayTime = millisec/1000.0;
00261 
00262         gettimeofday(&tv, NULL);
00263     startTime = tv.tv_sec + tv.tv_usec/1000000.0;
00264         do {
00265                 gettimeofday(&tv, NULL);
00266         elapsedTime = (tv.tv_sec + tv.tv_usec/1000000.0) - startTime;
00267     } while (elapsedTime < delayTime);
00268 }
00269 
00270 // Whether you define this depends upon your particular machine.
00271 // PCs reverse integer byte order, so this define is required.
00272 // For almost all other machines, you would omit this define.
00273 //
00274 // If your machine has 2 byte signed and unsigned integers, and
00275 // 4 byte signed integers, then you won't have to port the below code...
00276 #define INT_REVERSED
00277 
00278 
00279 // 2 byte signed short int
00280 char GetSignedShort(portstream_fd portstream, signed short *SHORTval, long
00281                     timeout) {
00282 #ifdef INT_REVERSED
00283         SerialBytesIn( portstream, (((unsigned char *) SHORTval)+1), 1, 
00284                        timeout);
00285         SerialBytesIn( portstream, ( (unsigned char *) SHORTval), 1, timeout); 
00286 #if DEBUG
00287         fprintf(stderr,"GetSignedShort: received <%d>\n", *SHORTval);
00288 #endif
00289 #else
00290         SerialBytesIn( portstream, ( (unsigned char *) SHORTval), 1, timeout);
00291         SerialBytesIn( portstream, (((unsigned char *) SHORTval)++), 1,
00292                        timeout); 
00293 #endif
00294         return TRUE;
00295 }
00296 
00297 // 2 byte signed short int
00298 char PutSignedShort(portstream_fd portstream, signed short *SHORTval) {
00299 #ifdef INT_REVERSED
00300         SerialBytesOut( portstream, (((unsigned char *) SHORTval)+1), 1);
00301         SerialBytesOut( portstream, ( (unsigned char *) SHORTval), 1); 
00302 #else
00303         SerialBytesOut( portstream, ( (unsigned char *) SHORTval), 1);
00304         SerialBytesOut( portstream, (((unsigned char *) SHORTval)++), 1); 
00305 #endif
00306         return TRUE;
00307 }
00308 
00309 // 2 byte usigned short int
00310 char GetUnsignedShort(portstream_fd portstream, unsigned short
00311                       *USHORTval, long timeout) {
00312 #ifdef INT_REVERSED
00313         SerialBytesIn( portstream, (((unsigned char *) USHORTval)+1), 1,
00314                        timeout);
00315         SerialBytesIn( portstream, ( (unsigned char *) USHORTval), 1,
00316                        timeout); 
00317 #if DEBUG
00318         fprintf(stderr,"GetUnsignedShort: received <%d>\n", *USHORTval);
00319 #endif
00320 #else
00321         SerialBytesIn( portstream, ( (unsigned char *) USHORTval), 1, timeout);
00322         SerialBytesIn( portstream, (((unsigned char *) USHORTval)++), 1,
00323                        timeout); 
00324 #endif
00325         return TRUE;
00326 }
00327 
00328 // 2 byte unsigned short int
00329 char PutUnsignedShort(portstream_fd portstream, unsigned short *USHORTval) {
00330 
00331 #ifdef INT_REVERSED
00332         SerialBytesOut( portstream, (((unsigned char *) USHORTval)+1), 1);
00333         SerialBytesOut( portstream, ( (unsigned char *) USHORTval), 1); 
00334 #else
00335         SerialBytesOut( portstream, ( (unsigned char *) USHORTval),    1);
00336         SerialBytesOut( portstream, (((unsigned char *) USHORTval)++), 1); 
00337 #endif
00338         return TRUE;
00339 }
00340 
00341 // 4 byte signed short int
00342 char GetSignedLong(portstream_fd portstream, signed long *LONGval, long
00343                    timeout) {   
00344     long i, incr = 1;
00345 
00346 #ifdef INT_REVERSED
00347         LONGval = (signed long *) (((unsigned char *) LONGval) + 3);
00348         incr = -1;
00349 #endif
00350         for (i=0; i<4; i++) { 
00351                 SerialBytesIn( portstream, ((unsigned char *) LONGval), 1,
00352                                timeout);
00353                 LONGval = (signed long *) (((unsigned char *) LONGval) + incr);
00354         }
00355         return TRUE;
00356 }
00357 
00358 // 4 byte signed short int
00359 char PutSignedLong(portstream_fd portstream, signed long *LONGval) {
00360 
00361 #ifdef INT_REVERSED
00362         SerialBytesOut( portstream, ((unsigned char *) LONGval)+3, 1);
00363         SerialBytesOut( portstream, ((unsigned char *) LONGval)+2, 1);
00364         SerialBytesOut( portstream, ((unsigned char *) LONGval)+1, 1);
00365         SerialBytesOut( portstream, ((unsigned char *) LONGval),   1);
00366 #else
00367         SerialBytesOut( portstream, ((unsigned char *) LONGval),4);
00368 #endif
00369         return TRUE;
00370 }

Generated on Thu Feb 1 15:31:52 2007 for WURDE by  doxygen 1.5.1