Forum Discussion

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

Altera Avalon Uart performance problem

I have been testing the Altera Avalon Uart by sending data to it from a different machine.

A program on the other machine sends 16kB of known data out its serial port which connects to the serial port on my uKit.

I am running the serial ports at 115200 baud.

I am having a problem where after about 4kB of received data, it begans losing the chars. Usually I only receive about 4-5kB total out of the entire 16kB sent.

My serial port is "/dev/ttyS1". If I enter "cat /dev/ttyS1 > /tmp/capture.txt", then open this file after the transfer, I can see this result.

I know that this uart does not have a FIFO. I'm trying to determine if this is likely the only problem I have or if there could be a software level issue as well.

I am working with a local FAE that is helping me to try a uart that does contain FIFO support, but I'm not seeing any difference in the behavior.

I've also thought about using the Open Cores uart16550. Has anyone ported this into their Nios II design? Does it work seemlessly with the standard 16550 compatible uart kernel driver?

I have lots of questions and I'm just wondering if anyone else has dealt with any of these issues.

I don't know if it is a hardware problem, software problem, or maybe...just maybe a user problem.

16 Replies

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

    Thanks for the suggestion. Now that you've mentioned this, it seems quite obvious that this would alleviate the problem. I've already implemented this on the receive side, so that a threshod is reached before generating the interrupt.

    I've verified that the receive_chars() routine will indeed read in all characters within the fifo on a single call.

    Will the transmit_chars() routine perform the same operation? It should be able to write characters to the transmit buffer until it is full (or nearly full).

    In looking at it, it appears that it will only send 1 character per interrupt. Am I right?

    Do you have some suggested ways of handling this?

    I can think of a possible implementation.

    Perform a do/while loop similar to the one in receive_chars() that will write chars to the tx fifo until it is full.

    If necessary, the uart w/ fifo support does provide new registers that allow software to see how many characters are in the fifo.

    This value could be used so the transmit_chars() routine knows when to stop writing data to the uart.

    If this fifo count info is important, I can add it to the serial driver. However, I do have some questions about how to add it.

    The registers below exist at offsets 6 and 7 of the uart. I'm not sure how to adjust the structure to make these readable from within the driver.

    np_uartrxfifoused address 6

    np_uarttxfifoused address 7

    Am I on the right track? Does the transmit_chars() routine need to be modified?

    Thank you very much for you help.

    P.S. If I get all of this working, I'll add a timer-based irq event into the uart so that if there are any characters in the rx buffer, an irq will be generated every X ms. This will ensure no characters are left sitting in the receive fifo because the threshold hasn't been reached yet.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    This post is supplemental to the previous one.

    One thing that is causing me confusion when using the NIOSserial.c driver is the following.

    Even when I'm not transmitting any characters, and only receiving them, the transmit_chars() routine is being called.

    Why does this happen? Shouldn't this routine only be called when characters are ready to be sent out?

    Any comments you might have in regards to these last questions will also help me out a lot.

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

    --- Quote Start ---

    originally posted by trk_golf@Mar 1 2005, 10:15 AM

    thanks for the suggestion. now that you've mentioned this, it seems quite obvious that this would alleviate the problem. i've already implemented this on the receive side, so that a threshod is reached before generating the interrupt.

    i've verified that the receive_chars() routine will indeed read in all characters within the fifo on a single call.

    will the transmit_chars() routine perform the same operation? it should be able to write characters to the transmit buffer until it is full (or nearly full).

    in looking at it, it appears that it will only send 1 character per interrupt. am i right?

    do you have some suggested ways of handling this?

    i can think of a possible implementation.

    perform a do/while loop similar to the one in receive_chars() that will write chars to the tx fifo until it is full.

    if necessary, the uart w/ fifo support does provide new registers that allow software to see how many characters are in the fifo.

    this value could be used so the transmit_chars() routine knows when to stop writing data to the uart.

    if this fifo count info is important, i can add it to the serial driver. however, i do have some questions about how to add it.

    the registers below exist at offsets 6 and 7 of the uart. i'm not sure how to adjust the structure to make these readable from within the driver.

    np_uartrxfifoused address 6

    np_uarttxfifoused address 7

    am i on the right track? does the transmit_chars() routine need to be modified?

    thank you very much for you help.

    p.s. if i get all of this working, i'll add a timer-based irq event into the uart so that if there are any characters in the rx buffer, an irq will be generated every x ms. this will ensure no characters are left sitting in the receive fifo because the threshold hasn't been reached yet.

    --- Quote End ---

    <div class='quotetop'>QUOTE </div>

    --- Quote Start ---

    In looking at it, it appears that it will only send 1 character per interrupt. Am I right?[/b]

    --- Quote End ---

    You are right. You have to customize it.

    <div class='quotetop'>QUOTE </div>

    --- Quote Start ---

    Perform a do/while loop similar to the one in receive_chars() that will write chars to the tx fifo until it is full.

    If necessary, the uart w/ fifo support does provide new registers that allow software to see how many characters are in the fifo.

    This value could be used so the transmit_chars() routine knows when to stop writing data to the uart.[/b]

    --- Quote End ---

    I don&#39;t see any problems.

    <div class='quotetop'>QUOTE </div>

    --- Quote Start ---

    If this fifo count info is important, I can add it to the serial driver. However, I do have some questions about how to add it.[/b]

    --- Quote End ---

    append them in the structure np_uart.

    <div class='quotetop'>QUOTE </div>

    --- Quote Start ---

    P.S. If I get all of this working, I&#39;ll add a timer-based irq event into the uart so that if there are any characters in the rx buffer, an irq will be generated every X ms. This will ensure no characters are left sitting in the receive fifo because the threshold hasn&#39;t been reached yet.[/b]

    --- Quote End ---

    or a kernel timer routine to check. Each RX interrupt will delay that timer further, and when there is no RX interrupt for long enough, the timer routine will be executed.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    originally posted by trk_golf@Mar 1 2005, 02:51 PM

    this post is supplemental to the previous one.

    one thing that is causing me confusion when using the niosserial.c driver is the following.

    even when i&#39;m not transmitting any characters, and only receiving them, the transmit_chars() routine is being called.

    why does this happen? shouldn&#39;t this routine only be called when characters are ready to be sent out?

    any comments you might have in regards to these last questions will also help me out a lot.

    thanks,

    --- Quote End ---

    <div class='quotetop'>QUOTE </div>

    --- Quote Start ---

    Even when I&#39;m not transmitting any characters, and only receiving them, the transmit_chars() routine is being called.[/b]

    --- Quote End ---

    not quite sure. Could be Xon/Xoff. You can check what was actually transmitted
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi all,

    is there a fix to this problem ?

    I mean, in 115200 bauds, I have a "ttyS2: 1 input overruns" when I transmit lots of data.

    Is the Cal avalon uart you are talking about a solution to my problem ?

    Is this fifo&#39;d uart available ?

    Is there a software fix to NIOSserial driver to solve this ?

    One more question :

    Did someone implement the hardware flow control in the NIOSserial driver ?

    Thanks in advance

    Best regards

    Pierre-Olivier