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