Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
16 years ago

Uart/fifo Uart problem

I tried to use a 2nd UART in my project.

ttyS0 I use for the terminal instead of Jtag UART.

ttyS1 I need for a communication interface.

With the ttyS1 I had some trouble:

1st problem)

Reading bytes with opening the ttyS1 device and using read did not return the expected amount of characters. I saw all characters beeing received by the interrupt and transferred to the flip buffer. But reading the flip buffer did not contain all the bytes. I drilled down into the kernel to find where the bytes got lost. Finally I found they got lost because of removing a lock.

In the file uClinux-dist/linux-2.6.x/drivers/char/tty_io.c in function flush_to_ldisc I commented out the lock.


//spin_unlock_irqrestore(&tty->buf.lock, flags);   //my change
 
disc->
receive_buf(tty, char_buf, flag_buf, count);
//spin_lock_irqsave(&tty->buf.lock, flags);          //my change

I am using kernel 2.6.23 but I saw that this piece of code still exists in 2.6.31 (the function is now in file uClinux-dist/linux-2.6.x/drivers/char/tty_buffer.c)

After applying this change to the kernel source read was responding with the right amount of bytes (and the terminal on ttyS0 still worked :-)

I have no idea why this change was necessary.

Can anybody verify or explain?

2nd problem)

Because at 115200 Baud occasionally I got the overflow set I tried out the Fifoed Avalon UART from the forum.

http://www.niosforum.com/pages/project_details.php?p_id=89&t_id=18

The component worked and the overflow went away.

When I stressed the component however it suddenly happened that I did not receive an interrupt anymore. Investigating the problem with signal tap showed that the interrupt stayed asserted forever.

My Nios has a clock of 84MHz and I set the baudrate to 115200.

The Fifo settings have been: Tx No Fifo, Rx Fifo 8 words, Timeout 0, Interrupt on every byte.

I use the NIOSserial.c driver without modification.

Has anybody experienced a similar effect?

Stressing the original UART component did not show this problem.

2 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi nacide,

    1. Please make sure you didn't cook the tty input,

    enable stty of busybox->coreutils->stty

    stty -F /dev/ttyS1 raw

    2. I rewrote the uart driver, altuart.c. Please try it either backport to 2.6.23 or check out the new kernel.

    Cheers,

    Hippo
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    1. I enabled stty and entered the cmd

    Still read returned only 1 byte when 3 bytes were in the queue.

    2. I changed the fifo settings to:

    No Tx fifo

    Rx fifo with 8 words length

    Interrupt after 4 bytes in fifo (value 1)

    Timeout: 1 character length

    With this settings the fifoed uart was stable and survived the stess test.

    The stress test was sendig a 1k text file to the nios from a terminal over and over.

    I did not look into the new altuart.c so far.

    My application looks like this:

    
    #include <termios.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/signal.h>
    #include <sys/types.h>
    #include "../wv_data.h"
    #include "../prot2.h"
    #define _POSIX_SOURCE 1 //POSIX compliant source
    #define FALSE 0
    #define TRUE 1
    /**
    * read is non blocking
    */
    main(int argc, char *argv)
    {
    int fd,iSize,i;
    struct termios oldtio, newtio; //place for old and new port settings for serial port
    struct sigaction saio; //definition of signal action
    unsigned char mesg=""; //buffer for where data is put
    int iTimeout,iStatus;
    long BAUD;
    long DATABITS;
    long STOPBITS;
    long PARITYON;
    long PARITY;
    BAUD=B115200;
    DATABITS=CS8;
    STOPBITS=0;
    PARITYON=0;
    PARITY=0;
    system("stty -F /dev/ttyS1 raw");
    fd=open("/dev/ttyS1", O_RDWR|O_NOCTTY|O_NDELAY);
    if(fd<0)
    {
    printf("%s,%s:Could not open /dev/ttyS1!",__FILE__,__FUNCTION__);
    exit(-1);
    }
    fcntl(fd, F_SETFL, FNDELAY);
    tcgetattr(fd, &oldtio); // save current port settings
    // set new port settings for canonical input processing
    newtio.c_cflag=BAUD|CRTSCTS|DATABITS|STOPBITS|PARITYON|PARITY|CLOCAL|CREAD;
    newtio.c_iflag=IGNPAR;
    newtio.c_oflag=0;
    newtio.c_lflag=0; //ICANON;
    newtio.c_cc=1;
    newtio.c_cc=0;
    tcflush(fd, TCIFLUSH);
    tcsetattr(fd, TCSANOW, &newtio);
    while(1)
    {
    iSize=read(fd,mesg,MAX_MESG_SIZE);
    if(iSize>0)
    {
    printf("Rxs=%d\n",iSize); //!!!
    for(i=0;i<iSize;i++)
    {
    printf("%02x ",mesg);
    }
    printf("\n");
    }
    if(iSize>0)
    {
    mesg=0x80;
    mesg=0xFF;
    mesg=0xAA;
    iSize=3;
    /*
    printf("Txs=%d\n",iSize); //!!!
    for(i=0;i<iSize;i++)
    {
    printf("%02x ",mesg);
    }
    printf("\n");
    */
    iStatus=write(fd,mesg,iSize);
    if(iStatus!=iSize)
    {
    printf("%s,%s: Send error,s=%d!\n",__FILE__,__FUNCTION__,iStatus);
    break;
    }
    } //end if iSize>0
    usleep(1); //give time to other processes
    } //while 1
    // restore old port settings
    tcsetattr(fd, TCSANOW, &oldtio);
    close(fd); //close the com port
     
    } //end of main