AM2434: AM243X: Problem with partial read of a UART message with DMA

Part Number: AM2434

Hi experts,

i encountered a problem when using UART with DMA to partially read a UART message.

I'm trying to read a package of unknown size with UART and DMA (PKTDMA instance) in two read calls. The first call reads the header with the length and the second call reads the rest of the package according to the length. With this implementation im getting random package drops though, because the DMA rearm between the first and second read doesnt work properly. In case of a package drop the UART read on the payload part finishes with less bytes read than requested, but the FIFO is empty. 

If i am using an interrupt based transfer (no DMA) or a delay between the header and payload part (with DMA) it works flawlessly, so i guess it is a timing issue with the rearm while the old DMA request is not properly finished.

Can you help me, how to fix this problem?

Cheers, 
Robin

  • Hi Robin,

    Please allow me sometime to revert back to this thread as I was caught up with some other tasks.

    Regards,

    Vaibhav

  • Hi Robin,

    Thanks for your patience.

    For a use case where the number of bytes is unknown, ad lets suppose we need to read the same.

    A combination of the following can be used to achieve it for non-DMA mode for UART:

    1. Timeout
    2. And basically getting to know exactly how many bytes have been read

    The timeout can be set pretty easily in the transaction before the UART_read call is issued inside your application.

    For reading the number of bytes read(this can be dynamic), you can refer this dedicated FAQ:  [FAQ] PROCESSOR-SDK-AM64X: Variable number of bytes read by UART 

    For UART DMA, the driver does not currently support partial UART reads or reads when the number of bytes to be received is unknown.

    Additionally, could you explain the flow of your application in points, so that I can help answer better.

    Regards,

    Vaibhav

  • Hi Vaibhav,

    thank you for your response.

    I am interested in solving my problem with DMA, but I will try and explain it better:

    I want to read one incoming UART transmission in the FIFO with two separate UART DMA calls. The first read tells me the size of the whole transmission, so both reads have a known number of bytes I want to recieve. But that implementation doesn't work. I keep getting random lost packages with the back to back UART DMA reads (on the already filled FIFO). 

    Should this theoretically be possible? And if yes, what might be the problems with the drivers at the moment?

    Regards, 
    Robin

  • Hi Robin,

    I want to read one incoming UART transmission in the FIFO with two separate UART DMA calls. The first read tells me the size of the whole transmission, so both reads have a known number of bytes I want to recieve. But that implementation doesn't work. I keep getting random lost packages with the back to back UART DMA reads (on the already filled FIFO). 

    Should this theoretically be possible? And if yes, what might be the problems with the drivers at the moment?

    This should not be a problem. I understood your statement.

    Is it true that UART RX on your board is connected to a UART TX or another external transmitter? If yes, then I would assume that you can fire or call UART Read with DMA enabled for UART twice in a row.

    Could you please share your application?

    Regards,

    Vaibhav

  • Hi Vaibhav,

    yes the UART RX on my board is connected externally. The application waits for an external message on UART, tries to read it in 2 DMA calls and on positive result, returns it back to the external part. I am using a custom board, but i tried to paste together all the important parts of the application and send it to you. 

    Cheers, 
    Robin
    UARTDMAexample.zip

  • Hi Robin,

    Have you incorporated cache writeback and invalidate in your application? I do see it, but can you incorporate writeback invalidate instead of just writeback and see?

    Regards,

    Vaibhav

  • Hi Vaibhav,

    yes i tried that just now with both read and send, but i still have the same behaviour. 

    Regards,
    Robin

  • yes the UART RX on my board is connected externally. The application waits for an external message on UART, tries to read it in 2 DMA calls and on positive result, returns it back to the external part. I am using a custom board, but i tried to paste together all the important parts of the application and send it to you. 

    I am going to try cloning the setup using just TI EVM.

    I am planning to use two UARTs in my application, lets say uart0 and uart1.

    This is the flow which I will follow:

    1. uart1 will be having some known data at its end in a buffer, lets say the data length will be 64 bytes.
    2. uart0 RX will receive 1 byte from uart1 TX with the value 64, as this value will determine that the next read which uart0 RX has to do is 64 bytes.
    3. Then the next read which uart0 RX does is of 64 bytes, in this case my uart0 RX buffer will be a big size lets suppose 1024 bytes as it will accommodate all the bytes sent from uart1 TX.
    4. Application ends.

    NOTE: This will be UART DMA reads itself.

    Do you want me to add anything else to the flow? Looking forward to your response.

    Regards,

    Vaibhav

  • Hi Vaibhav,
    that would be very helpful! 

    Two things i want to mention for the flow.

    1. The important thing is that when uart0 is recieving the 1 byte, uart1 needs to send the whole 65 bytes already, so uart0 needs to try to read the second part with a filled FIFO.
    2. Maybe try and loop the whole test a couple times (10-20), because it doesnt always fail for me.

    This isolated test will help me a lot, i'm looking forward to your results!

    Regards, 

    Robin

  • Hi Robin,

    So uart1 should just send 65 bytes once and be done, for example uart write for uart1 will be called just once.

    On the other hand, for uart0, uart read will be called twice, the first call being for the number of bytes to be read on the second call, and the second uart read for reading the n number of bytes.

    Do you want the structure to look like:

    • application starts
    • while loop(for about 20 times as per your test case)
    • uart1 TX sends data to uart0 RX
    • on uart0 RX side I call uart read twice
    • loop ends
    • application ends

    If this is something you also align on, I can test this tomorrow and let you know.

    Thanks,

    Vaibhav

  • Hi Vaibhav,

    yes that sounds perfect! And then maybe just some verification, whether the uart0 reads the second n number of bytes correct.

    Regards,
    Robin

  • Hi,

    Please expect responses in sometime.

    Thanks,

    Vaibhav