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.

TM4C129ENCPDT: Does UART BREAK clear FIFOs?

Part Number: TM4C129ENCPDT
Other Parts Discussed in Thread: EK-TM4C129EXL

The datasheet doesn't say much about BREAK signaling in the UARTs.

We are sending / receiving blocks of 64 bytes using uDMA with the UARTs. We are using BREAK as part of error handling to signal a request to clean up state and restart communication. This can happen in the middle of a message.

As part of cleaning up, we first stop the DMA from moving data between memory and the UART FIFOs. But what about information already in the FIFOs themselves?

What is the effect on the UART's FIFOs when that UART sends a BREAK, or when that UART receives a BREAK?

Does sending BREAK cause the Tx FIFO to be cleared?

Does receiving BREAK cause the Rx FIFO to be cleared?

If not, what is the proper way to clear the FIFOs?

  • Hello twelve12pm,

    Sending/receiving BREAK does not cause either TX or RX FIFO's to be cleared.

    For the TX FIFO, the recommended way to flush the transmit FIFO is by clearing bit 4 (FEN) in the line control register (UARTLCRH) (Source: Page 1312 of device datasheet). This can be done with the UARTFIFODisable() API.

    For the RX FIFO, the methods to flush the receive FIFO would be to either read out any junk data, or to reset the peripheral instance (Source: https://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/p/401599/1422732#1422732)

  • Ralph Jacobi said:

    For the TX FIFO, the recommended way to flush the transmit FIFO is by clearing bit 4 (FEN) in the line control register (UARTLCRH) (Source: Page 1312 of device datasheet). This can be done with the UARTFIFODisable() API.

    Is it permissible to clear FEN and then set FEN immediately? Or is it necessary to insert some wait states? The intent is to throw away the Tx FIFO contents but continue using FIFOs afterwards.

  • Can FEN be cleared / set without first disabling the UART by clearing UARTCTL.UARTEN?
  • twelve12pm said:
    Can FEN be cleared / set without first disabling the UART by clearing UARTCTL.UARTEN?

    I'm (per usual) "in the dark" here.     (w/this level of MCU-centric detail)

    That said - Ralph noted,  "UARTFIFODisable()."       Might you have (extended) this to "disabling the UART?"       IS there a difference - and/or ... IS it exploitable?

  • I'm doing some experiments on the EK-TM4C129EXL LaunchPad to find out.
  • Incidentally is there a more detailed user's guide for the TM4C UARTs, similar to this spru for the TMS320?

    www.ti.com/.../spru997c.pdf
  • You'll need vendor agent - or those more focused upon, "One & only one MCU brand."
    In most cases - prime features of the more advanced devices do (not) propagate (down) to those more basic...
  • Hello twelve12pm,

    twelve12pm said:
    Is it permissible to clear FEN and then set FEN immediately? Or is it necessary to insert some wait states? The intent is to throw away the Tx FIFO contents but continue using FIFOs afterwards.

    From what I've read, I see no issue with this, though it doesn't seem to be tested specifically. From the datasheet process, it looks like there is some time before the FIFO is used again, but I don't see anywhere that we have tested any sort of minimum time spec required to finish flushing the FIFO. A few wait states may be a good idea if you can afford them.

    twelve12pm said:
    Can FEN be cleared / set without first disabling the UART by clearing UARTCTL.UARTEN?

    Yes, and that is what the TivaWare UARTFIFODisable does. The datasheet just forewarns that doing so without disabling the UART means you could have unexpected behavior if either TX or RX process is going on, but I think in your case since you'd do it after a BREAK, you wouldn't have such occurring and should be safe to clear the flag without disabling the whole UART peripheral.

    twelve12pm said:
    Incidentally is there a more detailed user's guide for the TM4C UARTs, similar to this spru for the TMS320?

    Unfortunately, we don't have such a document for the UART peripheral.

  • Ralph Jacobi said:

    From what I've read, I see no issue with this, though it doesn't seem to be tested specifically. From the datasheet process, it looks like there is some time before the FIFO is used again, but I don't see anywhere that we have tested any sort of minimum time spec required to finish flushing the FIFO. A few wait states may be a good idea if you can afford them.

    Thank you for your reply.

    I understand that there isn't a tested minimum time spec but is there any hint as to what sort of time scales we might be talking about? On the order of a few clock cycles? Microseconds? Milliseconds? More than that? Some kind of approximate ballpark figure would be very helpful.

  • Hello twelve12pm,

    Hmm, well I am not sure off the top of my head on how to deterministically assess such a timing, but just from looking at page 1188, it indicates that the time it takes to re-program the control register is enough time to go ahead and re-enable the UART again. I wouldn't imagine that enable the UART before the FIFO flush is finished would be recommended. So based on that, I would say that we are in the clock cycles to microseconds range. I'll do a bit more digging in the AM if I can back that idea further and/or narrow the window down more.
  • Ralph Jacobi said:
    I'll do a bit more digging in the AM - see if I can back that idea further and/or narrow the window down more.

    May it be memorialized here - that,  "once again" - vendor's Ralph has gone,  FAR,  "Above-Beyond"  normal high-level  forum service!

    Even w/TEN + years here - never have firm/I encountered "this level" of  "UART Peripheral" detail.     And Ralph,  "Did not blink!"      (so easy to pass/retreat,  "give up" - especially as the request expanded...)

    In case the "AM effort" does not further amplify - the combination of,  "Ralph's determined effort & desire" - must be applauded - and deserves (very) special note!

  • Ralph Jacobi said:
    Hello twelve12pm,

    Hmm, well I am not sure off the top of my head on how to deterministically assess such a timing, but just from looking at page 1188, it indicates that the time it takes to re-program the control register is enough time to go ahead and re-enable the UART again. I wouldn't imagine that enable the UART before the FIFO flush is finished would be recommended. So based on that, I would say that we are in the clock cycles to microseconds range. I'll do a bit more digging in the AM if I can back that idea further and/or narrow the window down more.

    I assume you mean the datasheet -- but I brought up page 1188 and it's the ADC input equivalency / voltage reference page, not related to the UART or timing characteristics. Is there a different document I should be looking at?

    As far as the clock cycles / microsecond range, that is encouraging news. I appreciate your help very much.

  • cb1_mobile said:

    Ralph Jacobi
    I'll do a bit more digging in the AM - see if I can back that idea further and/or narrow the window down more.

    May it be memorialized here - that,  "once again" - vendor's Ralph has gone,  FAR,  "Above-Beyond"  normal high-level  forum service!

    Many green boxes will be awarded very soon. :-)

    cb1_mobile said:

    Even w/TEN + years here - never have firm/I encountered "this level" of  "UART Peripheral" detail.

    Normally I wouldn't delve into this level of peripheral detail. Communication is working wonderfully -- provided both sides of the communication power up together and never encounter an error. But as you know, we must be robust and have a good recovery / clean-up / resynchronization sequence. So far, everything I've tried hasn't quite worked, and it seems like the rabbit hole has led to a maze of twisty passages full of traps and dead ends. Between the UART, its FIFOs, DMA, the details of the datasheet, driverlib, my own code, and whatever other "gotchas!" I've run into, my head is exploding.

    When an error is encountered (signaled by a BREAK), I am trying to do something along these lines:

    Cancel any DMA Tx / Rx operations in progress with the UART in question

    Clean up the UART state -- including:

    - stop any Tx / Rx activities after the character in progress

    - clear the FIFOs

    - determine that the UART, FIFOs, DMA, and whatever else are in a known state

    - restart communication by retrying the last message

    - incrementing some error counter

    cb1_mobile said:

        And Ralph,  "Did not blink!"      (so easy to pass/retreat,  "give up" - especially as the request expanded...)

    In case the "AM effort" does not further amplify - the combination of,  "Ralph's determined effort & desire" - must be applauded - and deserves (very) special note!

    I appreciate Ralph's help very much. Thank you for recognizing it as well.

  • Might it be that (our firm's) use of "ARM MCUs from multiple sources" - may provide "further insight" into the (near) "Dead Sea" scrolls - you seek?

    Relying upon, "One and only one" MCU Info Source (even one as well motivated & able as Vendor's Ralph) may not expose,  "other valuable methods/solutions" - advanced by those in a (highly) overlapping field!

    Indeed there are likely to be (some) differences - yet I would note that our search/read/review of  "many related sources" - provides or provokes insights - which may not be available from (any) "one and only one"  source...

  • Hello twelve12pm,

    Error on my part, I probably had the wrong datasheet up (I bring up many throughout the day) and forgot to verify... The page in the DS for YOUR device is 1312. Sorry!

    Search for more info may need to wait until afternoon now, but it's on my queue for today (and cb1, I am not so sure I should be praised for my efforts yet, I may just be foolish to think I can find out more :) ).
  • Ralph,

    Firm/I believe - it is not "always & only" the results - which (alone) count!      Your "depth of response" (already) and willingness to "consult w/others" - signals exceptional dedication & sustained EFFORT.

    Simply terrific...

    Without "committing Blasphemy" (again) I've (gently) suggested that poster may "gain insight" by examining the efforts/methods of  "related others."     Surely there ARE differences - answer will unlikely reveal as "Cut/Paste" - yet the discovery of such  "techniques & mechanisms" has helped our present firm on "multiple occasions."      (and contributed to my co-founding - taking past tech firm Public - thus "proof of method!")

  • cb1_mobile said:

    Might it be that (our firm's) use of "ARM MCUs from multiple sources" - may provide "further insight" into the (near) "Dead Sea" scrolls - you seek?

    Relying upon, "One and only one" MCU Info Source (even one as well motivated & able as Vendor's Ralph) may not expose,  "other valuable methods/solutions" - advanced by those in a (highly) overlapping field!

    Indeed there are likely to be (some) differences - yet I would note that our search/read/review of  "many related sources" - provides or provokes insights - which may not be available from (any) "one and only one"  source...

    That is an interesting suggestion. Indeed, TM4C (123 and 129) represents my first experiences with TI and ARM. Prior experiences were with other vendors on non-ARM chips. It has been somewhere in the neighborhood of a year now, so I have already surmounted some pretty difficult obstacles. Hence the issues I'm having lately and my questions here are much less n00b and much more in-depth and detailed. Of course, those are the most difficult questions to answer.

  • My firm's (proven) results indicate that  "such expanded search"  proves often FAR (beyond) "interesting."       While this (related vendor) method is not (especially) intuitive - harnessing the brainpower of many - rather than a few - surely works to your advantage.      And is "missed" by so many - here - pity!

    There IS a "horror point" (potentially) here.      How - or even "do you react" - if (hypothetically) another's ARM MCU - "better provides" - just what you need?      What then?     And (forgive me) - does this not suggest that a, "More thorough review of MCU capabilities" - especially those (your UART one, here) which "drill so deep" - should have been "identified/searched/probed"  (to insure the best selection) FAR earlier?

    It is still possible - that in the absence of a (proper) solution (here) - you may glean ideas, work-arounds - perhaps even a "terrific solution" - from a  "broader search!"      Clearly - NO one firm has a "lock" upon "great & resourceful ideas and/or implementations!"        And you (may) be able to  "wrestle" that (or those) methods into  your current MCU & system - here.        (one hopes...)

  • cb1_mobile said:

    My firm's (proven) results indicate that  "such expanded search"  proves often FAR (beyond) "interesting."       While this (related vendor) method is not (especially) intuitive - harnessing the brainpower of many - rather than a few - surely works to your advantage.      And is "missed" by so many - here - pity!

    I agree. There is much to be said for learning from every source possible. From some, one learns what to do. From others, one learns what NOT to do! That's just as valuable!


    cb1_mobile said:


    There IS a "horror point" (potentially) here.      How - or even "do you react" - if (hypothetically) another's ARM MCU - "better provides" - just what you need?      What then?     And (forgive me) - does this not suggest that a, "More thorough review of MCU capabilities" - especially those (your UART one, here) which "drill so deep" - should have been "identified/searched/probed"  (to insure the best selection) FAR earlier?

    Yes there is that "horror point" but I there is this: Switching MCUs is a painful and costly endeavor! Even if I do find another MCU that offers the most perfect UART, or the most perfect "insert your wish list here," switching to that MCU inevitably requires going back to square one, climbing that steep learning curve once again, and means that you will run up against new problems that are difficult to solve. It is very easy to think that the grass is greener on the other side of the fence but the reason we are here right now is because THIS grass was greener from wherever we came from.

    We drilled quite deep when researching MCUs and MCU vendors, across numerous different criteria, technical and otherwise. We bought development kits from more places than you can shake a stick at, we installed more IDEs and developer tools than you want to know about, we ran tests, we did all sorts of things. We had good reasons for choosing TM4C and I stand by that decision 100%. It would be impossible to learn every detail of every MCU in the world, and to drill this deep, just to select a MCU. That is paralysis by analysis. At the end of the day, one must do one's due diligence but then one must make a decision and deal with whatever problems come.

    cb1_mobile said:


    It is still possible - that in the absence of a (proper) solution (here) - you may glean ideas, work-arounds - perhaps even a "terrific solution" - from a  "broader search!"      Clearly - NO one firm has a "lock" upon "great & resourceful ideas and/or implementations!"        And you (may) be able to  "wrestle" that (or those) methods into  your current MCU & system - here.        (one hopes...)

    Very possible.

    We are performing some experiments... I'll be back to post about our experiences.

  • Hello twelve12pm,

    While I was not able to find any further timing information, I did come across this snippet of code which I think you may be able to make use of:

        //
        // Wait for the UART FIFO to empty and then wait for the shifter to get
        // the bytes out the port.
        //
        while(!(HWREG(UART0_BASE + UART_O_FR) & UART_FR_TXFE))
        {
        }

    If you want to be sure the UART is in a known state too, you may also be interested in this expansion of that:

        //
        // Wait until the FIFO is empty and the UART is not busy.
        //
        while((HWREG(ui32Base + UART_O_FR) & (UART_FR_TXFE | UART_FR_BUSY)) !=
              UART_FR_TXFE)
        {
        }

    Hope that helps with your endeavor!

  • Dear Ralph,

    Thank you for all your help.

    I'll give these bits a try and post what we discover soon.

    Thanks again
  • Ralph,

    This looks very useful - I hope that poster Robert lands here - and comments.
    It is hoped that this proves advantageous to "12 squared" - yet on its own - this (still) proves of value... Mercî.
  • I'd like to say a profound "Thank You" to Ralph and cb1 for all your help on my very detailed questions about the UART peripheral.


    I will explain how we solved our recovery / resynchronization issue.


    Background: Communication uses a protocol of fixed-size messages. DMA moves data between memory buffers and the UART FIFOs for both receive and transmit. Communication is in a "ping-pong" fashion where one device is the "Master" of the communication. It sends a query, then waits for the reply, then sends the next query, etc. The other device works in reverse. It must first receive a message, then send the reply, then wait for the next message, etc.


    This works great but the issue we had was that if one of the devices encountered some error, whether that's a UART receive error, one MCU resetting in the middle of communication, or other issues that disrupt or corrupt communications, that caused the communication sequence to get out-of-sync between the two devices, so that all further messages became incoherent due to their header, CRC, etc., not being in the correct positions.


    We solved this as follows:


    On power-up, we initialize the UART and uDMA channels normally, but we do not enable the UART, we do not enable its FIFOs, and we do not give it access to the device pins yet. The device pins are in GPIO mode, Tx as output, Rx as input, and we drive Tx low.


    Once the remainder of software has initialized and we are ready to begin communications, we perform a handshake to make sure that both sides of communication are ready and synchronized.


    When we detect a BREAK, or when we need to send a BREAK, we place the pins into GPIO mode. Once in that mode, we clean up the UART and perform the handshake to get both sides of communication back into synchronization with each other.


    The handshake is very simple:


    1. Both sides must drive their Tx pin low for at least two character frames.


    2. When the Master detects that the other side has been driving its Tx pin low, it drives its Tx pin high and waits for the other side to do the same.


    3. When the other side detects that the Master has been driving its Tx pin high, it drives its Tx pin high as well.


    This sequence signals to both sides that they are in sync with each other. Both sides have stopped uDMA transfers in progress and "cleaned up" their UARTs to remove any stale data from before. Both sides can now re-enable their UARTs and give control of the pins back to the UARTs, and start with a fresh slate.


    Rationale: We first drive Tx low. When both parts power up simultaneously, both are in GPIO mode. However if one is in UART mode and the other goes to GPIO mode because it reset or detected an error, step 1 of driving Tx low for two frames will register as a BREAK on the device that is still in UART mode, causing it to switch to GPIO and run the handshake sequence.


    We end with driving Tx high because that is the "at rest" state of the UART Tx line when no transmission is in progress.


    We ensure that the reading remains low or high, respectively, for at least two character frames so that we won't mistakenly recognize data bits being transmitted from the other MCU as the expected signals.


    There are some timing characteristics that must be respected:


    1. When Tx is driven low for more than one full character time, that registers as a BREAK on the receiving UART. Documentation near UARTBreakCtl() states that for proper transmission of a BREAK, it must be asserted for at least two complete frames.


    2. When UART transmission and reception is stopped by turning off UARTCTL bits UARTEN, RXE, and TXE, the datasheet states that if the UART is disabled in the middle of a transmission, it completes the current character before stopping, so we must allow one character frame time length for that. It was recommended that we wait for current character transmission or reception to complete before disabling the FIFOs to flush the Tx FIFO, to avoid an undefined outcome.


    3. Earlier in this thread there was discussion of how long it takes to fully clear the Tx and Rx FIFOs. Ralph narrowed that down to somewhere in the clock cycles to microseconds range. The time length equivalent to two character frames should be more than ample.


    To ensure that we respect these timing characteristics, the handshake and uDMA/UART cleanup is driven by a timer generating a periodic interrupt. The load value is calculated to the time length of two characters. In this interrupt, we implement a state machine which proceeds through the handshake sequence, one step per two character frame time length. We only activate the timer when it is necessary to perform this sequence. During normal operation the timer is unused and is not triggering interrupts.


    To ensure that we respect timing issue 2 above, we stop uDMA transfers and disable the UART in the first step, then we disable the FIFOs in the next step after transmission of any character should have completed. We do not re-enable the FIFOs until we are fully synchronized with the other host and ready to start / resume sending messages with DMA.


    A few surprises that we ran into, and how we solved them:


    Before initiating a new uDMA transfer, our code checks that the channel is in UDMA_MODE_STOP, as a precaution to prevent us from clobbering a transfer in progress. When we cancel a DMA transfer in progress, the channel appears to remain stuck at UDMA_MODE_BASIC, preventing future transfers from being able to start. We remedied this by calling uDMAChannelTransferSet() with UDMA_MODE_STOP as part of uDMA cancellation. Note that because of the function's ASSERT checks, we must pass valid values for the buffer pointers and transfer size to this function. Therefore we created a dummy buffer and pass the pointer and size of that. Since we are stopping uDMA, the dummy buffer should remain untouched.


    uDMA completion notification differs between TM4C129 and TM4C123, and our codebase targets both. To remedy this, we use preprocessor logic to choose if we call UARTIntClear() with UART_INT_DMATX / UART_INT_DMARX when running on TM4C129 or uDMAIntClear() with the channel mask when running on TM4C123.


    Disabling the UART with UARTDisable() causes a delay because UARTDisable() waits in a while() loop until all FIFO contents are sent. This is great when things are working correctly and you don't want to truncate a communication in progress under normal circumstances. But because we want to cancel ongoing communications quickly and resynchronize the two hosts, we do not want to continue transmitting what is in effect stale / unwanted data. So we disable the UART by turning off the UARTEN, TXE, and RXE bits of UARTCTL directly, without calling UARTDisable(). We copied the line of code that we needed from UARTDisable() into our own code. Recall that we disable the FIFO later in our sequence to respect the timing characteristics mentioned previously.


    Having jumped through all these hoops, our tests are finally showing that this process is working and that communication stops, resynchronizes, and starts effectively. We increment a counter each time such resynchronization is necessary and we will monitor this to see how often this happens in practice.


    Again, thank you to Ralph and cb1. I hope this discussion will be helpful to someone.
  • Wow - deep thanks for your willingness to present such detail - and for recognizing the efforts of several (especially Ralph)!

    Now 0420 (CST) and today is a "School Day." (all right - a work day)

    I'll be sure to give your latest detail a very good read - and I hope to induce friend Robert to read/review/comment - as well.

    I have crack staff "reading/reviewing" the UART sections of several (other) ARM MCUs (both M4s & M7s (my fav)) - and we'll see if we can tease out "their methods" - to provide you "even more/further" Methods of Attack. (there can NEVER be - too many Arrows - in your quiver!) or something...