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.

TMS320F28388D: No clear path to achieve efficient data handling with CM-UART

Part Number: TMS320F28388D

Hello

We are using the TMS320F28388D processor and we must have a UART link to other devices that supports an efficient, high-speed interface.

We have decided NOT to use an SCI UART on the CPU cores because

a) it only goes up to 12.5Mbps (at max core clock rate of 200MHz)

b) it has limited baud rate choices.

b) it does not support DMA operations.

c) we are using the CPUs for other intensive operations.

So, we are looking into the CM-UART that is accessible by the ARM core. On the surface, it appears to have most of what we need:

a) goes up to 15.625Mbps (at 125MHz core clock).

b) it has a fractional baud rate divider for more baud choices

c) it is supported by the uDMA module.

We are now being stymied by what appears to be limitations in the CM-UART design. This is not meant to criticize, I realize there are design decisions that needed to be made, but I get the feeling I must be overlooking something because it seems the CM-UART is being hobbled by the following artifacts:

a) The introduction to the CM-UART in the TRM says "programable FIFO length". But I have not found a register that can set the FIFO length. There appear to be only two choices. (A) FIFO length of 1 (i.e. disable the FIFO) or (B) FIFO length of 16. At 15.625Mbps, a byte is received every 640ns. So, if I don't use the 16-deep FIFO I have to set the UART interface to the highest priority just to keep up.

b) If I do use the FIFO, the minimum RXIFLSEL value is 1/8 the FIFO depth. That is 2 bytes. In our system, the data comes in bursts and is not guaranteed to be an even number of bytes, so if an odd number of bytes is received, then one byte can get stuck in the FIFO without generating an interrupt. Also, depending on how the interrupts are serviced, this situation could probably happen if an even number of bytes was sent.

c) So, we turned our attention to the uDMA. This module appears to be able to pull data from the UART regardless of the FIFO fill level, but the uDMA module itself only allows the user to specify a size and and end address. The ping-pong feature could be used to switch between buffers, but the uDMA module itself does not appear to have any registers that tell the user how much data has been transferred. It only tells you when a transfer is complete. So, if the received data only partially completes a uDMA transfer there is no way to pull the data from the partial buffer and restart the transfer. So, again, we are in a situation in which data is stuck in a buffer waiting for more data arrive in order to trigger an interrupt. Or, we could set the uDMA transfer size to 1 and again have to deal with an interrupt on every single byte of data (not efficient).

Is there some way around this?

Thanks

-Ray

  • Hi Ray,

    1. The Programmable FIFO length meant the configurable interrupt level for the FIFO.

    2. The interrupt is always triggered when the FIFO status is greater than or equal to the set level. So inside the RX interrupt handler you can read the bytes from FIFO until the FIFO is empty (RXFE of UARTFR UART_isDataAvailable() API then UART_readCharNonBlocking() ) instead of just reading the number of bytes for which interrupt was configured.

    If the prior burst length is known you can wait for all the bytes to be received before exiting using UART_readChar() API.

    If you think that 1 or 2 bytes get stuck in the FIFO for long time because the fill level is not reached you can always configure a timer interrupt to read the left over bytes at a periodic rate.

    Regards,

    Yashwant 

  • 1) Not "think", I know... it is already happening.

    2) message length is variable and not known in advance. This is not uncommon in communication systems.

    3) Using a timer (or just polling for that matter) to flush out remaining bytes is not a hallmark of an efficient or low-latency design. And mixing a timer ISR with the UART ISR poses problems. Might as well just run the timer alone and forgo the UART ISR altogether. At 15.625Mbps, this will require a >100KHz timer at a high priority.

    4) The fact that the uDMA is not mentioned in the reply suggests that there is no practical way to use it.

    I guess I will just need to chalk this one up as one of those quirky things that I will need to work around as best I can.

  • Hi Ray,

    I think with the given information you've identified the possible implementation trade-offs for a truly unknown message length for each message packet.  

    Does the beginning of the message packet provide the message length after a fixed number of bytes? What is the minimum message length? Can you take a DMA interrupt after say the first 2 bytes or first 4 bytes (in FIFO mode) to decode the message length, then use something like a one-shot timer (configured based on the remaining message duration) or re-configured DMA transfer duration to come back when the DMA should be done moving the even portion of the message, grab any odd bytes manually from the FIFO, and begin decoding the message?   

  • OK... a lot of fair questions, but none of them really get to the nub of the matter. Had either the CM-UART had a 1/16 full interrupt or the uDMA had a register with the count of bytes already processed then this whole thing would be a non-issue.

    As of now, my plan is to dump the UART interrupt and the uDMA and just use a high-priority timer ISR to essentially poll the UART FIFO. Not elegant or efficient as many CPU cycles will be wasted checking for data when the FIFO is empty. Latency will be poor (~10us), but at least the code will be compact and performance will be deterministic.

    You can go ahead and close this ticket.

    Thanks

    -Ray