This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM3352: UART hardware flow control

Part Number: AM3352


Hi all,

We use a loopback connector on RS232 port, which rx connect to tx pin, and rts connect to cts pin.

And linux-serial-test @ https://github.com/cbrake/linux-serial-test is used to test flow control

the command is:

> linux-serial-test -p /dev/ttyS1 -s -e -c -r

-s, --stats Dump serial port stats every 5s
-e, --dump-err Display errors
-c, --rts-cts Enable RTS/CTS flow control
-r, --no-rx Don't receive data (can be used to test flow control)
when serial driver buffer is full
the expect result is the program should stop sending data after 4096 bytes is sent if flow control work, cause the serial driver buffer size if 4096.
But the test result is the program keep sending data after 4096 bytes is sent.
Do you know how to verify RTS/CTS?
thanks!

BR,
Denny

  • What board is this? What Linux version? Have you tried connecting two boards?
  • The board is our product board,  kernel version is Linux 4.1.21, haven't try two board yet.

    What tools do you used to verify flow control between two board?

  • Hi Denny,

    Do you observer data lost when the sent date exceed 4096 bytes?

    BR
    Tsvetolin Shulev
  • One more question: Are the RTS/CTS flow control pins properly pin muxed in Linux configuration?

    BR
    Tsvetolin Shulev
  • the two pins are configured in device tree. 

    0x178 (PIN_INPUT_PULLUP | MUX_MODE0) /* (D18) uart1_ctsn.uart1_ctsn: RS232C_CTSN */
    0x17C (PIN_OUTPUT_PULLUP | MUX_MODE0) /* (D17) uart1_rtsn.uart1_rtsn: RS232C_RTSN */

  • yes, maybe there is some data lost, here is the log, you can tell rx does not equal to tx, even we count in bytes in buffer

    Linux serial test app
    /dev/ttyS1: count for this session: rx=61824, tx=65520, rx err=0
    /dev/ttyS1: TIOCGICOUNT: ret=0, rx=429552, tx=425984, frame = 0, overrun = 0, parity = 0, brk = 0, buf_overrun = 0
    there are 0 bytes in read buffer
    there are 4080 bytes in write buffer

  • By the way, the DMA is enabled for current uart driver.

  • Hi Tsvetolin Shulev,

     

    Have you tested hardware flow control?

    Did you see the same issue?

     

    BR

    Haifeng

  • Haifeng,

    Yes, we have tested hardware flow control. I'm not sure what you are seeing is related to hardware flow control. Since the DMA is enabled, the UART FIFO will continuously serviced by the DMA, thus the 4096 UART FIFO limit may never be met. The UART doesn't know that the application is not reading the data. This seems consistent with what you are seeing.

    Have you put a scope on the RTS/CTS line to see if it is being asserted/deasserted? If it is, that would indicate that hardware flow control is being used properly.

  • Hi RonB,

    actually 4096 is a tty level limit, under kernel tty level, there is another buffer in serial port level, it's about 124k bytes.

    here is test log:

    root@localhost:~# serialtest -p /dev/ttyS1 -s -e -c -r
    Linux serial test app
    /dev/ttyS1: count for this session: rx=0, tx=69615, rx err=0
    /dev/ttyS1: TIOCGICOUNT: ret=0, rx=65424, tx=65520, frame = 0, overrun = 0, parity = 0, brk = 0, buf_overrun = 0
    /dev/ttyS1: count for this session: rx=0, tx=139230, rx err=0
    /dev/ttyS1: TIOCGICOUNT: ret=0, rx=127232, tx=135135, frame = 0, overrun = 0, parity = 0, brk = 0, buf_overrun = 7840
    /dev/ttyS1: count for this session: rx=0, tx=208845, rx err=0
    /dev/ttyS1: TIOCGICOUNT: ret=0, rx=127232, tx=204750, frame = 0, overrun = 0, parity = 0, brk = 0, buf_overrun = 77440
    /dev/ttyS1: count for this session: rx=0, tx=278460, rx err=0
    /dev/ttyS1: TIOCGICOUNT: ret=0, rx=127232, tx=274365, frame = 0, overrun = 0, parity = 0, brk = 0, buf_overrun = 147040
    /dev/ttyS1: count for this session: rx=0, tx=348075, rx err=0
    /dev/ttyS1: TIOCGICOUNT: ret=0, rx=127232, tx=343980, frame = 0, overrun = 0, parity = 0, brk = 0, buf_overrun = 216640
    /dev/ttyS1: count for this session: rx=0, tx=413595, rx err=0
    /dev/ttyS1: TIOCGICOUNT: ret=0, rx=127232, tx=409500, frame = 0, overrun = 0, parity = 0, brk = 0, buf_overrun = 282160

    you can see that tx number continue increased, mean while  rx number  stoped at 127232, and buf_overrun keep increasing.

    according to my understanding if flow control works, the buffer overrun should never happens, and tx should stop when receive buffer is full.

    BR

    Haifeng

  • Haifeng,

    Thank you for your continued testing and sharing your results. Looking at the issue further, we've identified a path used when DMA is enabled where the UART driver doesn't properly handle information from the tty layer to make h/w flow control kick in. This problem was reproduced on our latest production kernel, v4.9. We are working on a fix for this issue on that version, v4.9. I will provide that fix when it is available. It will be your responsibility to back port that fix to your kernel if you choose to stay with v4.1.

    Please understand that many people take time off at this time and it will likely be sometime in January when I can provide this fix.

    Kind regards,
    Ron
  • Haifeng,

    We have posted a fix to the mainline Linux driver here:

    www.spinics.net/.../msg633288.html

    You will need to back port this change to the 4.1 version you are using, but it should allow you to use Flow Control with DMA as you originally requested.