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.

TL16CP754C - How clear UART FIFO



Hello,

We are using the TL16CP754C for communication. Common speed settings are 115200,8,N,1.

From time to time we saw some (1,2)  bytes in RX FIFO on start receiving. I think UART FIFO didn't clear well. Please, help how to clear all FIFOs.

Our FIFO purge function use FCR to clear FIFO:

OUTREG8(&pUartRegs->FCR, FCR_Copy | UART_FCR_RX_FIFO_CLEAR | UART_FCR_TX_FIFO_CLEAR);

but next actions are not easy, and I confused:

Datasheet say "FCR is read only register", therefore after FCR write I need:

- waiting for several milliseconds (1 msec used now)

or

-  use readonly IIR register bits 7-6: copy  of FCR(0)  FCR(0) bits and waiting for 0 it both. (yes, documentation is "excellent")

First way work from time to time (as I noted before).

Second way completly doesn't work, becouse IIR is always 0xC1, and I never saw it's 6 and/or 7 bit will clear after FCR FIFO clear command.


What is wrong in my code? How to real clear TL16CP754C FIFO with 100% guarantee?


BW,

Alexey Kuzmin

  • Kuzmin Alexey said:
    Datasheet say "FCR is read only register"

    Whereever you mean to have read this, it's wrong, maybe you was confused by the Interrupt identification register (IIR), which is situated at the same address like the FIFO control register (FCR). IIR is read only, FCR is write only - what you concern to depends only on writing or reading from that same address. Read here: tl16c754c.pdf.

    Also look carefully in this document for which register values the FCR depends on. Are you sure not to disable FIFO mode through writing 0 to FCR(0)?

    For further requests it might be helpful if you'd spend somewhat more of your code.

    Best regards,
    Joern.

     

  • Thank you for answer, Joern.

    Sorry, It's my error in original mesage, when I wrote, I should write "FCR is write only register".

    You are right, IIR and FCR have same address 0x10.

    Of cource, I have datasheet your notices.

    I am sure about FIFO enabling.

  • First of all I have to say that I don't know if there is any issue existing with that chip. But as long as no others give a statement concerning that...

    Kuzmin Alexey said:

    IIR is always 0xC1 [...]

    I am sure about FIFO enabling.

    So that the bits 6+7 of  IIR are always "1" seems clear for me, as they are copies of the FCR FIFO enable bit 0 - which in your case seems always to be set to "1", as you announced. If your code above is complete, I assume, this bit is set by FCR_Copy?

    Have you already tested the Line Status Register LSR? Maybe there are errors while receiving and LSR bit 7 is set (I am not sure how that is correctly handled and if that leads to received bytes)?

    Regards,

    Joern.

     

  • Yes, the FCR_Copy value is =1 by init.

    May be you're right and IIR should have 6 and 7 bit on when FIFO is on (If 6 and 7 bits are just copy FCR bit0). I suggested IIR registers 6&7 usage as more complicated. The datasheet says about FCR bits:

    bit 1: 0 - No change, 1 - clears receive FIFO and resets it’s counter logic to zero. Will return to zero after clearing FIFO.

    bit 2: 0 - No change, 1 - clears transmit FIFO and resets it’s counter logic to zero. Will return to zero after clearing FIFO.

    But there is no ability to read FCR (it's write only register) in this chip, and my suggestion was "IIR[6-7] is read available copyes of FCR[1-2]". Becouse I should wait for FCR bit 1&2 "return to zero" (don't know, how) I tried to wait for IIR bit 6-7 reset. If it not right, how to better check FIFO clearing end?

    Can you explain how to better test LSR value? Should I check bit7 before or after FIFO clear?

    ----

    BW,

    Alexey.

  • It sounds as currently you were polling the data. In this case I assume you already look into LSR for bit 0 changing to "1", which indicates that data is available within the Rx FIFO. So at least for debugging purposes I would check for any error bits within that LSR register and if there occure some, then this possibly was a valuable information concerning the observed problems.

    This "Will return to zero after clearing FIFO." I find irritating as well. I assume they meant only, that you will not have to set this bit back to "0" yourself, as sometimes in completely other hardware context this is necessary for reset bits.

    Did you already try to look for the behaviour before and after FIFO cleaning by observing at least the Rx FIFO via LSR bit 1?

    Regards,
    Joern.

     

  • FYI, we don't use polling, we using interrupts generation. I told about 6&7 bits in IIR upper, not about other bits.

    Joern said:
    Did you already try to look for the behaviour before and after FIFO cleaning by observing at least the Rx FIFO via LSR bit 1?

    I didn't yet. I will look and inform tomorow.

  • Hello,

    I added LSR conrol in all code performing FIFO init, also RX interrupt handler make visible LSR value (only the first run).

    Log is following. I forget to said, we use UART loopbacking of TX to RX. I suggest, baudrate changing make TX drop from time to time and receiver try initiale RX ("just READ 0x00"). Am I right or not?

    Test transfer started.
    +PurgeComm LSR 0
    -PurgeComm final LSR 0
    SetBaudRate(freq:14745600, baudrate: 9600, divisor 95)
    LSR 0
    +PurgeComm final LSR 0
    RX
    Int: just READ 0x00
    RXInt: Linestat 0x21
    LSR 0
    -PurgeComm final LSR 1
    SetBaudRate(freq:14745600, baudrate: 115200, divisor 8)
    sbuf init started!

  • I don't have the original message indicating what the issue is with this device so I will make just a brief comment about resetting and clearing hte FIFO

    The FIFO Control Regsiter (FCR) is write only. Below is an example of initializing the UART and resetting (clearing) the FIFO's:

    /* Port 1 - Channel A */
     outportb(LCR_UART1, 0x80);     /* Enable divisor access registers*/
     outportb(DLL_UART1, 0x0b);     /* set divisor           */
     outportb(DLM_UART1, 0x00);
     outportb(LCR_UART1, 0x03);     /* Set character to 8,N,1 data        */
     outportb(FCR_UART1, 0xC7);     /* Enable and clear FIFOs, Rcv thresh=60  */    
     outportb(IER_UART1, 0x0F);     /* Enable all interrupts */
     outportb(MCR_UART1, 0x00);     /* Disable flow control   */

    The Receive FIFO will clear after all characters are read from the FIFO and there are no remaining receive errors. The LSR is  read only and indicates the status of the FIFOs.

  • Finally, all is working. Thanks for all!