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.

L138: Comment on CPPI DMA TX

Hi,

I have the CDC ACM (virtual com port) working in FIFO mode. I am enabling the DMA so that I can free the CPU from data transfer.

While I am configuring the CPPI DMA for TX, I found that the DMA must be disabled (TXGCR[n].TX_ENABLE = 0) when I submit the HPD into the USB Endpoint TX submit queue.

If the DMA is enabled while submitting the HPD, the descriptor will end up in the wrong queue (by looking at the PEND[n] register). For example, when I submit HPD for Endpoint 2 into queue 18 while the DMA is enabled, PEND[0] shows me that the descriptor is end up in the queue 0.

I am not sure if this is the correct behaviour because the sample code in sprufm9h-july 2010 enable the DMA first and submit the descriptor into the queue later. Although it calls function enableCoreTxDMA() after descriptor submission, that function does not set TXGCR[n].TX_ENABLE.

By the way, I am using RNDIS transfer mode.

rgds,

kc Wong

  • Hi,

    In addition to the  observation in the first post, I need a delay after descriptor submission, then only can enable the DMA by setting TXGCR[n].TX_ENABLE.

    Without the delay, the descriptor submission will always end up in the wrong queue, which is queue 0 in this case.

    If I enable the DMA after delay, it works sometimes (but not always), I can see "Hello World\n" being transmitted from the device and interrupt is generated.

    I am not sure what could be wrong. Any advice ?????

    rgds,

    kc Wong

    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    UINT8 buffer[] = "Hello World\n";

     PacketDescriptorInfor infor;
     infor.channel = CDMA_CHANNEL2;
     infor.direction = CDMA_TX;
     infor.pktLength = strlen((const char *) buffer);
     infor.returnQueue = txCompletionQ;
     infor.bufferLength = strlen((const char *) buffer);
     infor.bufferPtr = (UINT32) &buffer[0];
     infor.nextDescriptorPtr = 0;

    CDMADrv_InitHostPacketDescriptor(&hostPacketdescriptor, &infor); /* Init the HPD */

    CDMADrv_SubmitToTxQueue(txSubmitQ, (void *) &hostPacketdescriptor); /* submit HPD to the submit queue */

    taskDelay(20); <--- Delay is needed before enabling

    CDMADrv_EnableTxChannel(CDMA_CHANNEL2); /* Enable channel 2 by setting TXGCR[n].TX_ENABLE */

     

     

  • KC,

       Is your software configuring Queue Manager (QM) Diversion Register at all?

     Also - what is the contents of the Packet Return Queue # configured in your HPD Word 2?

     

     

  • Hi Drew,

    No, the SW is not configuring DIVERSION at all. I suppose the register should have the value after reset which is all zero.

    I use Queue 24 for Packet Return Queue # configured in HPD Word 2.

    I have a channel configurtion table like below.

    rgds,

    kc Wong

     LOCAL ChannelConfiguration CHANNEL_CONFIG_TBL[ ] = {
      /* txCompletionQ */ /* rxCompletionQ */ /* txSubmitQ */ /* rxSubmitQ[] */
      {24,    26,     16,    {0, 0, 0, 0}}, /* Channel 1 */
      {24,    26,     18,    {1, 1, 1, 1}}, /* Channel 2 */
      {25,    27,     20,    {2, 2, 2, 2}}, /* Channel 3 */
      {25,    27,     22,    {3, 3, 3, 3}} /* Channel 4 */
    };

     

  • Hi Drew,

    For the observation in the first post, I can always make sure the DMA for that channel is disabled before submit the HPD, so that the HPD will not end up in queue 0.

    But the observation in the second post is bothering me. First, adding delay before enabling the DMA will slow down the data transfer. Second, it does not work always, this is the worst part.

    For that, I need to have extra retry code. Below is an example for channel 2. I have a counter to count how many retry. Sometimes it can be 0 retry, but the other time it can be more than 300 retries.

    1. Disable DMA, clear TXGCR[n].TX_ENABLE

    2. Submit HPD to queue 18

    3. While loop to read PEND0 until the bit corresponding to queue 18 is set

    4. Enable DMA, set TXGCR[n].TX_ENABLE

    5. Short delay

    6. Read PEND0 to check if the HPD end up in queue 0. If yes, retry by starting from step 1 again.

    Any commnet on this ? I need help and advice on this.

    rgds,

    kc Wong

     

  • Hi,

    The problem is turned out to be a cache coherency problem.

    If the OS provides cache-safe buffer, use it for the Memory Region. Else just make sure data cache is flushed before descriptor submission.

    rgds,

    kc Wong