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.

CC3235SF: A Faster UART with larger buffer

Part Number: CC3235SF


To achieve a higher speed of UART communication we are looking to see if there is an implementation that uses DMA and interrupts rather than blocking and polling.

We also need a circular buffer of ~32kB to allow the MCU to process the information coming in when it has the clock cycles to do so.

Is this something that has already been done?

  • Hi,

    We will look into this and get back to you.

    Best,

    Saurabh

  • Hi Nicholas,

    DMA can be used with UART (please refer to chapter 6 of the TRM).

    Check the uart2callback driver example as a reference.

    It uses the uart2 driver (https://software-dl.ti.com/ecs/SIMPLELINK_CC32XX_SDK/5_20_00_06/exports/docs/drivers/doxygen/html/_u_a_r_t2_8h.html).

    This is probably what you are looking for (though the original uart driver can also work with DMA).

    It seems that UART2_Mode_CALLBACK would fit your application requirements. 

     

    br,

    Kobi

  • Hi Kobi, I don't believe your answer is correct.

    The devil is in the details. Let's look at some.

    1a. UART data is asynchronous and the number of bytes varies.Interrupt on 1 byte would NOT work.(See next statement)

    2a. A baud rate of 3,000,000 = 300,000 bytes per second.

       Unreasonable interrupt at 1/300000. or even 8/300000 with fifo

    3a. Contiguous packet size could be from 1 byte up to 16k bytes.

    Callbacks won't work.

    Here is what I have done several times with other hardware to solve this problem...I know how to do it with other UART and DMA IP blocks, but I am a newbee with the CC3235SF.

    1b.Create a DMA circular buffer of size 32k.

      (Or two 16k ping-pong buffers)

    2b.Maintain Head/Tail pointers via the foreground task loop.

    3b.Create a Timer interrupt about every 20mSec and check the Head/Tail pointers. Flag the foreground task to call the process data function to consume the data received and update the Head pointer.

    So here are the questions that I don't have answers and can't find example code.

    A. Can the uDMA handle a 32k (or two 16k) buffer?

    B. Can I read the circular buffer pointer of the last written byte address from the uDMA peripheral registers in order to update the tail pointer?

    Please only respond if you either have answers to questions A and B or have working example code to handle the data flow as detailed in 1a-3a.

    Thanks...Daniel

  • Please refer to the CC3235x TRM (https://www.ti.com/lit/pdf/swru543) for details about the uDMA.

    If you don't know the size of the transaction and needs to read byte by byte, DMA may not be the right method.

    Br,

    Kobi

  • Hi Kobi,

    The customer has read through those sections before and has implemented this type of function on another platform. There were a couple of specific questions asked:

    • Can the uDMA handle a 32k (or two 16k) buffer?
    • Can I read the circular buffer pointer of the last written byte address from the uDMA peripheral registers in order to update the tail pointer?

    Can you please address these directly? Its not clear from the TRM. 

    Thanks,
    Nick

  • uDMA can handle up to 1024 transfer items (of 8/16/32 bits each) - so up to 4KB in a single transaction.

    I'm not sure i understand the 2nd question, why can't the software calculate the last written byte? 

    Anyway it is calculated by the driverlib (see udma.c) to update the control block.

  • I am not talking about the arbitration size.

    I am trying to build A CIRCULAR BUFFER.

    Let me try to ask the question in a different way.

    Given:

    The UART peripheral will generate the DMA request upon receiving bytes into its rx FIFO.

    The arbitration size will is based on the UART DMA request. (See section 6.2.3.5)

    All interrupts are OFF.

    The uDMA starts with a destination pointer at the first location of a 16Kb memory location.

    The uDMA will increment the destination pointer as the multiple UART based DMA requests complete.

    THE QUESTIONS NOT ANSWERED IN THE TRM OR UDMA.C CODE :

    How does the uDMA know when it reaches the end of the 16Kb destination block?

    How can I set it to be circular so that at the end of 16Kb it goes back to the first byte of the block?

  • You are talking (circular buffer) about a sw implementation, but from the hw perspective each UDMA transaction has a limit of 1024 transfer items. It would be the software (typically in interrupt context) that sets the next transaction and handles the buffer wrap-around.

    See the UART driver implementation.

    Br,

    Kobi

  • So in the TI document SWRU543A  in the UART section 6.2.3.5:

    When DMA operation is enabled, the UART asserts a DMA request on the receive or transmit channel when the associated FIFO can transfer data. For the receive channel, a single transfer request is asserted whenever any data are in the RX FIFO. A burst transfer request is asserted whenever the amount of data in the RX FIFO is at or above the FIFO trigger level configured in the UARTIFLS register.

    Are you saying the UART peripheral CAN NOT automatically assert a burst uDMA for the FIFO, in hardware, as indicated in the above statement ?

    Are you also saying the only way to have the UART hardware transfer through DMA is to assert the request inside a UART ISR because that is how the driver works?

  • Burst mode is supported, but the SW sets each transaction so Ring Buffer implementation is controlled by the SW.

    Br,

    Kobi