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.

TMDX654IDKEVM: AM65xx: MCASP RX DMA issue

Part Number: TMDX654IDKEVM

PDK: pdk_am65xx_1_0_7

Dear TI Support Team,

This post is linked to my previous question here:

TMDX654IDKEVM: AM65xx: MCASP DMA issue - Processors forum - Processors - TI E2E support forums

I continue researching the MCASP interface and have a few questions that I would like to clarify.

I based my test application on the audioSample_io.c test, which is located in the PDK.

I made the following changes to the MCASP configuration:

  • The data is transmitted in Burst mode;
  • RX path operates in ASYNC mode (using external MCASP0_ACLKR and MCASP0_AFSR);
  • RX and TX AFIFO are enabled;
  • DMA is enabled;
  • TX and RX DMA Ratio for McASP is 1;
  • four TX serializers and four RX serializers;
  • each channel transfers 16 32bit words in parallel (DMA transfer of 64 32bit words)

I use an external loopback to test the data transfer. MCASP0_ACLKX is connected with a jumper to MCASP0_ACLKR, MCASP0_AFSX is connected to MCASP0_AFSR, MCASP0_AX0/1/2/3 are connected to MCASP0_AR0/1/2/3 respectively.

The main modifications that I made in the test application relate to the initialization and execution of DMA requests to send and receive data.

I made the following assumptions and modified the original test application as following:

I assumed that if I put descriptors of the TX and RX DMA Transfer Requests in the appropriate Ring Accelerators and don't pop them out of there after execution, then for each subsequent DMA TrReq invocation I need simply write to the appropriate DoorBell registers.

Question: Please correct me if my assumption is wrong and I cannot rely on this approach to work.

Therefore, I initialize the TX Ring Accelerator by allocating space in it for a single DMA Transfer Request descriptor. I initialize the corresponding TX DMA TrReq, which copies a 64 32bit word from memory to the corresponding DMA channel and place its descriptor in the RA. In order to initiate the data transfer, I write to the appropriate DoorBell register. After the request has been executed it is not removed from the RA. In order to perform a second data transfer, I simply write again to the DoorBell register.

In fact, I have unwrapped the mcaspSubmitChan() implementation used in prime() and simplified it, leaving only the DMA TrReq initialization for TX and RX and their placement in RA.

Since the transmission works, I can conclude that my assumption is correct. I am testing the transmission with an oscilloscope and the data looks fine:

 

But I have problems with receiving data, the reason for which I am trying to understand.

For the RX path I initialize the RA and DMA TrReq in the same way. I create a single RX DMA TrReq and place its descriptor in the appropriate RA. I then write to the appropriate DoorBell register to increment the count of pending requests on the RA.

I expect that when the RX AFIFO accepts RNUMEVT, it will initiate RX DMA TrReq execution and copy data from the RX AFIFO to Destination memory will occur.

The data is copied, but the data is fragmented.

Graphically it looks as follows:

There is no data loss. Somehow I get all the data I send, but it is copied to the destination memory in two parts. The first part of the data is copied when the RX DMA TrReq is executed and the second part when the next TX DMA TrReq is executed. I got the impression that after the data transfer is done, some of the received data is copied to RX AFIFO and some is still in RX BUF and the subsequent data transfer "pushes" it to AFIFO.

I'm trying to understand why this happens and have done some experiments.

I perform two operations in sequence:

First I do a data transfer. I execute the TX DMA TrReq to transmit 64 32 bit words and expect the transmitted data to be received in the RX AFIFO and the MCASP_RFIFOSTS [7-0] RLVL register will indicate the number of data bytes received. However, this does not happen and the MCASP_RFIFOSTS [7-0] RLVL value is 0.

Then, even though MCASP_RFIFOSTS [7-0] RLVL is 0, I do an RX DMA TrReq and get some data.

In this regard, I have a few questions:

Question: Why does MCASP_RFIFOSTS [7-0] RLVL always equal 0 even though I pass 64 32 bit words?

Question: Is there any way to see the contents of RX AFIFO?

Question: Is there any way to reset the contents of RX AFIFO (clear AFIFO)?

Question: Why is the RX DMA TrReq is executed even though there is not enough data in the AFIFO? According to TRM the RX DMA TrReq should be generated when the AFIFO contains MCASP_RFIFOCTL[7-0] RNUMDMA data bytes?

Despite the fact that the idea is quite simple, its implementation contains many technical details that must be taken into account. In order for us to be able to substantively discuss this issue I have prepared an archive with my test project.  It consists of two parts:

  • am65x_36_McASP_Int_test_a53_008_exp (A53) - Initializes McASP, DMA, RA, TX and RX TrReq and places them on RA. After the initialization is done I get the addresses of the corresponding DoorBell and pass them to the PRU.
  • am65x_36_PRU_to_ARM_int_gen_asm_001_exp (ICSSG_PRU) - It implements a simple loop that writes to the corresponding DoorBell registers to execute the corresponding TX and RX DMA Transfer Requests.

 

Could you please take a look at it and give your comments? I would appreciate it if you could point me to errors in my implementation that cause me to get fragmented data.

Thank you in advance!

Kind Regards,

Yury. 

am65x_36_McASP_Int_test_a53_008.zip