From - Sun Dec 29 21:33:06 1996 Path: news.unizar.es!news.rediris.es!pith.uoregon.edu!arclight.uoregon.edu!enews.sgi.com!news.sgi.com!news.bbnplanet.com!su-news-hub1.bbnplanet.com!news.Stanford.EDU!tip-mp18-ncs-11.stanford.edu!user From: yesavage@leland.stanford.edu (Jerry Yesavage) Newsgroups: comp.sys.sgi.bugs Subject: Continued Serial Port Problem Date: 29 Dec 1996 07:01:10 GMT Organization: Stanford University Lines: 286 Message-ID: <yesavage-2812962300580001@tip-mp18-ncs-11.stanford.edu> NNTP-Posting-Host: tip-mp13-ncs-9.stanford.edu I have posted on this before- a problem connecting a SGI 4D310 to a FFRASCA flight simulator. I have succeded in getting the communication going but have a very strange error on one port: I appreciate very much your responses from this group. This has driven me crazy and the sim is still down- it may represent some hardware glitch in the sgi machine or a C problem- but I doubt it. I have the serial ports reading the sim data. /dev/ttyd1 reads sim position data fine. The /dev/ttyd2 is interrogated by the command "IA\n" and returns a radio frequency- in this case "123.45\n" . Attaching a dumb terminal to ttyd2 I can communicate with no problem to the sgi machine - can also use a mac terminal emulation program. Also attaching to sim I can communicate fine with a terminal. AND, if I use Kermit on the sgi machine it communicates fine with the SGI machine, i.e. I use connect and get the "123.45" for the "IA\n". BUT, when the sgi machine is attached to the sim and I use a C program, the sgi machine drops invariable the THIRD number of the radio frequency- so I get 12.45 not 123.45!!!! I get the same error if I switch ttyd1 for ttyd2. A member has submitted a potential solution which it appears to me can shut down most of the processing that goes on around ttyd2 in C, but the code suggested (appended below) does not compile completely. The statement: fcntl(serport,F_SETFL,FNDELAY); produces the error: Argument type doesn't match prototype structure description; prototype: int is different from actual: struct A shortened version of the program is presented below with the output following still showing the missing character. Now having spent over 100 hours on this problem I am beyond desperation. I am going to spend the day trying to create a system call from C that perhaps used CU or KERMIT to get that data. *****************************program******************************* #include <stdio.h> #include <fcntl.h> #include <termio.h> #include <errno.h> #define IASTRING "IA\n" #define IESTRING "IE\n" #define IKSTRING "IK\n" struct termio tio; int success,commoff; /* communications byte offset */ int f1,fd,wc,nc,n,nc2; /* comm. file descriptor JYADD*/ char inbuf[1], outbuf[10], outbuf2[10], t_buf[20]; /*JYADD*/ int px,py,pz; /* plane position */ initcomm() { char *mem1,*zero; printf("\n\n\n0002 inside initcomm\n"); /*fcntl(fd,F_SETFL,FNDELAY); compilation error*/ /*if ((fd = open("/dev/ttyd2",O_RDWR)) < 0) OLD*/ if ((fd = open("/dev/ttyd2",O_RDWR)) < 0) /*NEW*/ { perror( "Can't open ttyd2 port" ); exit(1); } printf ("FDFDFDFDFDFDFDFD fd = %d\n",fd); if (ioctl(fd, TCGETA, &tio) < 0) { perror("getattr failed"); } printf ("TIO TIO TIO 001 tio = %o\n",tio); /*baseline tio prior to changes */ /*tio.c_iflag |= PARMRK + BRKINT + INPCK; OLD*/ tio.c_iflag = 0; /*NEW*/ tio.c_iflag |= INPCK; /*OLD*/ /*tio.c_cflag |= CS8 + CREAD + CLOCAL; OLD*/ tio.c_cflag = B9600 | CS8 | CLOCAL | CREAD; /*NEW*/ tio.c_lflag = 0; /*OLD NEW*/ tio.c_cc[VMIN] = 1; /*OLD NEW*/ /*tio.c_cc[VTIME] = 1; OLD*/ tio.c_cc[VTIME] = 0; /*NEW*/ if (ioctl(fd, TCSETA, &tio) < 0) perror("setattr failed"); ioctl(fd,TCFLSH,0); /* flush out initial noise */ ioctl(fd,TCFLSH,1); /* flush out initial noise */ printf ("TIO TIO TIO 002 tio = %o\n",tio); /*printout tio to show it changes*/ } main() { printf("\n"); system ("stty -a </dev/ttyd2"); initcomm(); printf("\n"); system ("stty -a </dev/ttyd2"); printf("\n"); n=0; while (n < 500000) { n++; if (n == 1) { wc = write(fd, IASTRING, sizeof(IASTRING)-1); printf("************************************************writing IASTRING wc = %d\n",wc); nc = 0; } if (n == 250000){ printf("01 Inside a-loop n = %d\n",n); /* Now - perform the read*/ do { nc2 = read( fd, inbuf, 1 ); if (nc2<0) fprintf( stderr, "error on read" ); printf("02 n = %d inbuf[0] = %d %c nc2 = %d nc = %d\n",n,inbuf[0],inbuf[0],nc2,nc); if(inbuf[0] != '\n' ) nc++; printf("************************************************loop %d\n",nc); } while (inbuf[0] != '\n' & inbuf[0] != '\r'); /* end of reading... */ } /* end of n == 80 */ nc = 0; if (n == 490000) n = 0; } } *****************************output******************************* speed 9600 baud; line = 1; intr = DEL; quit = ^\; erase = ^H; kill = ^U; eof = ^D; eol = ^@; swtch = ^@ lnext = ^V; werase = ^W; rprnt = ^R; flush = ^O; stop = ^S; start = ^Q -parenb -parodd cs8 -cstopb hupcl cread clocal -loblk -tostop -ignbrk brkint ignpar -parmrk -inpck istrip -inlcr -igncr icrnl -iuclc ixon ixany -ixoff isig icanon -xcase echo -echoe echok -echonl -noflsh opost -olcuc onlcr -ocrnl -onocr -onlret -ofill -ofdel tab3 speed 9600 baud; line = 1; intr = DEL; quit = ^\; erase = ^H; kill = ^U; eof = ^A; eol = ^@; swtch = ^@ lnext = ^V; werase = ^W; rprnt = ^R; flush = ^O; stop = ^S; start = ^Q -parenb -parodd cs8 -cstopb -hupcl cread clocal -loblk -tostop -ignbrk -brkint -ignpar -parmrk inpck -istrip -inlcr -igncr -icrnl -iuclc -ixon -ixany -ixoff -isig -icanon -xcase -echo -echoe -echok -echonl -noflsh opost -olcuc onlcr -ocrnl -onocr -onlret -ofill -ofdel tab3 0002 inside initcomm FDFDFDFDFDFDFDFD fd = 3 TIO TIO TIO 001 tio = 1511414005 TIO TIO TIO 002 tio = 4014005 ************************************************writing IASTRING wc = 3 01 Inside a-loop n = 250000 02 n = 250000 inbuf[0] = 49 1 nc2 = 1 nc = 0 ************************************************loop 1 02 n = 250000 inbuf[0] = 50 2 nc2 = 1 nc = 1 ************************************************loop 2 02 n = 250000 inbuf[0] = 46 . nc2 = 1 nc = 2 ************************************************loop 3 02 n = 250000 inbuf[0] = 52 4 nc2 = 1 nc = 3 ************************************************loop 4 02 n = 250000 inbuf[0] = 53 5 nc2 = 1 nc = 4 ************************************************loop 5 02 n = 250000 inbuf[0] = 13 nc2 = 1 nc = 5 ************************************************loop 6 ************************************************writing IASTRING wc = 3 01 Inside a-loop n = 250000 02 n = 250000 inbuf[0] = 49 1 nc2 = 1 nc = 0 ************************************************loop 1 02 n = 250000 inbuf[0] = 50 2 nc2 = 1 nc = 1 ************************************************loop 2 02 n = 250000 inbuf[0] = 46 . nc2 = 1 nc = 2 ************************************************loop 3 02 n = 250000 inbuf[0] = 52 4 nc2 = 1 nc = 3 ************************************************loop 4 02 n = 250000 inbuf[0] = 53 5 nc2 = 1 nc = 4 ************************************************loop 5 02 n = 250000 inbuf[0] = 13 nc2 = 1 nc = 5 ************************************************loop 6 ************************************************writing IASTRING wc = 3 01 Inside a-loop n = 250000 02 n = 250000 inbuf[0] = 49 1 nc2 = 1 nc = 0 ************************************************loop 1 02 n = 250000 inbuf[0] = 50 2 nc2 = 1 nc = 1 ************************************************loop 2 02 n = 250000 inbuf[0] = 46 . nc2 = 1 nc = 2 ************************************************loop 3 02 n = 250000 inbuf[0] = 52 4 nc2 = 1 nc = 3 ************************************************loop 4 02 n = 250000 inbuf[0] = 53 5 nc2 = 1 nc = 4 ************************************************loop 5 02 n = 250000 inbuf[0] = 13 nc2 = 1 nc = 5 ************************************************loop 6 ************************************************writing IASTRING ****AD NAUSEUM Dr. Cs original message: -------------------------------------- Date: 12/26/96 11:32 To: Jerry Yesavage From: Dr. Charles E. Campbell Jr. Hello! Are you getting any data through to the SGI? Note the TCFLSH commands below; that can obnoxiously block your read call from working. /* --------------------------------------------------------------------- */ Subject: Opening Serial Ports For 8-bit Communications Opening a serial port is easy! Use int ioport; ioport= open("NameOfPort",O_RDWR|O_NDELAY|O_APPEND) and you should get a readable and writable port. The name of the port is often something like "/dev/ttyf1", but you'll have to check your "man serial" pages first. The problem is getting that serial port to do what you want. Be aware: serial ports typically come configured to handle terminals, so they might map CR to CR-LF, map CR to LF (or vice versa), drop the high bit on 8-bit bytes, come up with some baudrate that you won't want, do modem-like handshaking, etc. Furthermore, they may have something "in the port" and will need "flushing" first (or else they'll hang!). Typically, you'll want to use ioctl to get the serial ports in the shape you need: #include <termio.h> typedef struct termio TermIO; TermIO serport; fcntl(serport,F_SETFL,FNDELAY); if(ioctl(ioport, TCGETA,&serport)) {...error...} serport.c_lflag = 0; /* no line discipline */ serport.c_iflag = 0; /* no input processing */ serport.c_cc[VMIN] = 1; /* one character at a time */ serport.c_cc[VTIME]= 0; /* no receive timeout */ serport.c_cflag = {baudrate} | CS8 | CLOCAL | CREAD; serport.c_oflag &= ~OPOST; /* no output post-processing */ and the baudrate will be B300, B1200, B2400, etc. You may want it to ignore characters resulting from various sorts of errors: serport.c_iflag |= (IGNBRK) /* ignore framing error characters */ serport.c_iflag |= (IGNPAR) /* ignore framing error characters */ Finally, you'll want to make use of these changes: ioctl(ioport,TCSETA,&serport); /* set new port parameters */ ioctl(ioport,TCFLSH,0); /* flush input */ ioctl(ioport,TCFLSH,1); /* flush output */ /* --------------------------------------------------------------------- */ -- Phone: 415-852-3287 Fax 415-852-3297 http://www-leland.stanford.edu/~yesavage