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.

TM4C1294NCPDT UARTFR register TXFE bit reading

Other Parts Discussed in Thread: EK-TM4C1294XL

Hi!

I am trying to make UART echo project for further use.

Receive and transmit functions use both FIFO and interrupts and work fine, except that when i call UART0_Send(); second time immediately after previous call, data from both calls is mixed:

const uint8_t FW_ID[] = {"u0_echo_1f "__DATE__" "__TIME__};

int main(void)
{
  system_init();
  
  rxi = 0;
  UART0_Send((uint8_t *)FW_ID, strlen((const char *)FW_ID));
  UART0_Send("\r\n>\r\n", 5);

like this:

u0_echo_1f Jan 19
>
 2016 09:30:37

Obviously this happens because second UART0_Send call manages to insert data into UART TX FIFO before Interrupt finishes sending the previous call data.

To repair this i need to wait for UARTFR register TXFE bit becoming zero. Or even better ho have an interrupt setting a Boolean flag when this happens.

Unfortunately i do not find a Peripheral Driver Library function to do this.

I need something like:

while (UARTFR.TXFE) {};

Or interrupt on UARTFR.TXFE bit going zero.

I use EK-TM4C1294XL board with CCS v.6.1.1,TI compiler v. 5.2.6 and TivaWare_C_Series-2.1.2.111 libraries.

I am attaching the whole project.

Any suggestions?

Thank you.

Dmitri

01f.u0_echo.zip

  • Hello Dmitri,

    The issue might be with the way you have written the UART0_Send function in "uart0.c" file. The UART is configured to interrupt on TX. You are transmitting from UART0_Send function as well as from UART Interrupt handler. Is there a reason to do this? Why can't you handle all the transmission from the UART Interrupt handler and use UART0_Send function to set up buffer.

    This may not be the reason for this error, but I would recommend that you debug and clean up this piece of code. Unless there a good reason, always try to have one piece of code do a specific task. It is a good programming practice as it will reduce the effort to debug, test and maintain code in the long run.

    Hope this helps!

    Thanks,
    Sai
  • Hello Sai,

    Thank you for your advice.
    The idea is to free processor for other tasks. Those functions are intended to work under FreeRTOS. UART transmission takes a very long time, At 115200 baud tm4c makes about 10400 cycles while UART is sending one byte of data at this rate.
    If you could advise me how to make non-blocking UART transmission in a FreeRTOS task i will be grateful.

    Best regards,
    Dmitri

  • Hello Dmitri,

    Stellaris Sai said:

    Why can't you handle all the transmission from the UART Interrupt handler and use UART0_Send function to set up buffer.

    The above statement stands even when using RTOS. Using UART Interrupt is a very good method for non-blocking transmission - with or without RTOS. You are on the right track.

    The issue I was pointing to was that you have two non-sequential blocks of code (one function and the other interrupt), that are trying to do the same job (to transmit data over UART). Maybe you have handled these code blocks such that they will work as expected. But it is a better to avoid such a scenario.

    Sai

  • Dmitri,

    Read up on queues, pipes, semaphores and other inter process communication techniques. The techniques are pretty universal and work with or without an RTOS.

    Robert
  • Believe that poster's been given quite good advice from both responders:

    • Sai - use great care and/or combine, "two non-sequential blocks of code"
    • Robert - semaphores are the usual (best) choice @ my firm

    I may have missed (or the detail did not arrive) but one method of lessening the (comparatively)    s...l...o...w... UART traffic is to devise a basic encoding scheme - which substantially reduces the volume of UART traffic.   While not (always) possible or appropriate - consideration should be afforded such encoding.   As you likely know - encoding works best when the variability, range & size of messages is minimal (or may be made minimal via design) and the related "decoding" can be performed (at each UART end) "outside" of the UART.

  • I'd use a pipe or queue myself. If I only had semaphores I'd use them to build a pipe. However, a prebuilt pipe would save me some trouble and probably be more efficient.

    There was a book written on uC-OSII that contained a lot of details both on what and why but also how of various RTOS structures and techniques, it's probably still available but uC-OS itself has, I think, been overtaken by FreeRTOS (which does have documentation on-line but really isn't a good tutorial).

    Robert

    Embedded Systems Programming probably has some good introductory overviews on-line as will in their archives.
  • We note that our usual, "Go to" source..."Robert's Bookshelf" advertises/invites fewer visitors than (today's) Vegas strip.  (which has ended long existing, "FREE Parking" and now seeks 10 (USD) for unaided, Street (yes street) parking!)   [this reporter "received" such intel - denies any, "First Hand Experience!"  (pay no attention to multiple Aces - secreted w/in each sleeve...)]

  • Thank you all for useful suggestions.
    I will read on RTOS queues and semaphores, thank you for suggesting uC-OSII book, i will look into it.

    But first i will try to simplify UART0_Send function and move all data copy from TxBuffer to UART FIFO into UART_INT_TX part of the UARTIntHandler.
    Question, if all this data copy to UART FIFO is under: if (ui32Status & UART_INT_TX)
    how to generate the very first UART_INT_TX interrupt without writing anything to UART FIFO?

    And my original question how to catch TX FIFO End-Of-Transmission event is still unanswered.

    Dmitri
  • Dmitri Tsvetikov said:
    And my original question how to catch TX FIFO End-Of-Transmission event is still unanswered.

    Queues/FIFOs/Pipes was the answer

    Robert

  • Hello Dmitri,

    The bit EOT in the UARTCTL register can be used to trigger a UART Transmit interrupt only after all the data has left the UART TX FIFO.

    Please refer UARTCTL and UARTIFLS registers in the UART section of the datasheet to understand the different ways in which the UART Transmit interrupt can be triggered.

    Thanks,
    Sai