Interrupt Driven Serial Port Reading problems

Hey all!

I am having difficulty reading from the serial port, it is being controlled by interrupts when the data comes in, it is supposed to be roughly 1Hz (depends on GPS signal and stuff)
I am encountering 2 problems:

1: Is that when i read using Interrupts so the serial port interrupts when the data is ready to be read, that happens roughly 1Hz, then after that i for some reason get like roughly 20(give or take) interrupts one after another which also reads the data (its not supposed to do this, because the program on the IMU that i am using outputs data roughly every 1Hz).

2: After i perform the read I noticed that the data in the serial port doesn;t get updated for some reason, and the data that is in the serial port is only maxed at 2048 bytes(anyone know why this is?), it only gets updated when i perform an InterruptWait() and corresponding InterruptUnmask() when this happens I found out that the data in the serial port gets refreshed 8 bytes at a time, so eventually after say 2048 - 167 *(amount of reads), the data in the serial port runs out and ruins my whole output.
To counteract that problem i put in a while loop (which is in the code below).
To make sure I only read when there is more then 167 bytes.

CODE: FOR READING FROM SERIAL PORT

while(1){

     InterruptWait( 0, NULL );

//THE LOOP BELOW IS WHAT I USE TO MAKE SURE THERE IS MORE THEN 167 BYTES BEFORE I READ
while (tcischars(fd)<(167))
{
InterruptUnmask( IRQ, intr_id );
InterruptWait(0,NULL);
}

numRead = read(fd, buffer, SIZE_BUFFER);
printf("\n numREAD %d\n",numRead);
/WRITE/
printf("%s",buffer);
write(outfd,buffer,SIZE_BUFFER); //writing to file on PC/104

  /* Reenable this interrupt since writing is finished */
 InterruptUnmask( IRQ, intr_id );

  }

CODE FOR SETTING UP SERIAL PORT
The IMU has to be read at 9600baud No flow contorl no parity and read 8 Bits at a time (ASCII)

int open_port(void)
{
int fd; /* File descriptor for the port */
struct termios termios_p; /termios structure/
fd = open("/dev/ser1", O_RDONLY | O_NOCTTY );
if (fd == -1)

  {
        perror("open_port: Unable to open /dev/ser1 - ");
        return 0;
  }
  else
        printf ("port opened\n");
  tcgetattr(fd, &termios_p);                /*read in the current settings*/
  cfsetispeed(&termios_p, BAUD_RATE);       //set input baud
  cfsetospeed(&termios_p, BAUD_RATE);       //set output baud
  termios_p.c_cflag &= ~PARENB;       //no parity bit (error checking bit)
  termios_p.c_cflag &= ~CSIZE;
  termios_p.c_cflag |= CS8;           //set number of bits to 8
  termios_p.c_cflag &=~ IHFLOW ;      //disable input h/w flow control
  termios_p.c_cflag &= ~OHFLOW ;      //disable output h/w flow control
  tcsetattr(fd, TCSANOW, &termios_p);
  return (fd);

}

Can anyone please help me?
I am going crazy :frowning:

Thanks.

The IMU i am using the the PhoenixAX by O-Navi

Thanks so much for your help

I probably can’t help much. I now that there is a single call that you can make that will allow you to read from the serial port and set criteria for when to return. This includes things like, wait for 167 bytes, and if you like, wait for up to x ms for the 167 bytes and also if bytes start coming in, only allow y ms between bytes before returning. I forget the name of the routine, but I looked it up last week.

As to why you might get 8 bytes per interrupt, your UART might have a data FIFO and a threshold set above 1. That’s quite common today.

Hey Maschoen, i think your referring to readcond(), yeh im playing around with that too, Mario replied to my post on the foundry for qnx told me my whole aproach was wrong (which it is) I changed it drastically.

How can i remove that 8Byte thing completely?

Look at the serial driver’s options, but…

You don’t want to.
Well there are circumstances in which you might want to.
The FIFO usually has a flush timeout of one byte.
So you will might receive 160 bytes and then have to wait for 8 more before you get the last 7 bytes.
This is generally foolish as you lose the advantage of the FIFO.
If you set the threshold at 1 you will need 8 interrupts to get 8 bytes instead of 1.

Of course there are applications where you absolutely want that last byte exactly when it comes in.