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.

Urgent!!! ACPY3_wait() function doesn't wait really

I am using EVMOMAPL137 and trying to use EDMA3 with ACPY3 API

I am able to copy data from one location to another(from external memory(SDRAM) to internal(L2)).

But when I want to use ACPY3_wait() function in order to wait the transfer be completed, I fail.

I am trying to read just after the ACPY3_wait() function, and I see that copy process is not completed yet.

How can I be sure that data was really copied??

 int c,e,*copied=(int*)0x11801FF9, *expected=(int*)0xc0001FF9;
 ACPY3_Params tcfg;
 IDMA3_ChannelRec dmaTab;
 IDMA3_Handle dmaHandle;
 int status;
 *copied=0;
  DMAN3_init(); 
  ACPY3_init();
  
    /* Set up the DMA Channel descriptor with the transfer parameters  */
    dmaTab.numTransfers = 1;
    dmaTab.numWaits = 1;
    dmaTab.priority = IDMA3_PRIORITY_LOW;
    
    /* The ACPY3 transfer protocol will be used as the IDMA3 protocol object 
     * This object defines the memory requirements and the initialization and 
     * de-initialization functions for the protocol's environment */
    dmaTab.protocol = &ACPY3_PROTOCOL;
    dmaTab.persistent = FALSE;
 
    /*
     * On success this call will return a valid DMA channel handle with the 
     * attributes defined above 
     */
    status = DMAN3_createChannels(0, &dmaTab, 1);
 if (status == DMAN3_SOK) printf("DMAN3 is ok\n");
 dmaHandle = dmaTab.handle;
 ACPY3_activate(dmaHandle);
 tcfg.transferType = ACPY3_1D1D;
 tcfg.srcAddr     = (void *) 0xc0000000;
 tcfg.dstAddr     = (void *) 0x11800000;
 tcfg.elementSize  = 8192 * sizeof (int);
 tcfg.numElements  = 1;
 tcfg.numFrames    = 1;    
 tcfg.waitId      = 1;
 ACPY3_configure (dmaHandle, &tcfg, tcfg0);    
 ACPY3_start (dmaHandle);
 ACPY3_wait (dmaHandle);


 c=*copied; // one of the last locations to campare
 e=*expected;


 if(c == e) printf("success to copy by the end\n");
 else printf("fail to copy by the end\n");

 

  • Issues with ACPY3_wait most likely have to do with improper configuration of the heaps that are used to hold internal data structures etc for DMAN3. For the DMAN3.heapInternal configuration, make sure you are using a heap that is 'actually' in internal memory. Could you double check that ?

    See this link for more information:-

    http://tiexpressdsp.com/index.php/Framework_Components_FAQ#Why_does_my_alg_hang_in_ACPY3_wait.28.29.3F

  • Yes they are in internal memory.

    İn fact my problem is not hanging on wait function, just the opposite, not waiting enough the transfer to be completed.

    I can see all transfer completed from memory window by the way. There is no problem with transfer, the problem is how can I be sure that transfer is completed.

    When I benchmark with using wait function and without using it they are different. wait function waits some time really, but as seen below when I try to read just after the wait, I see that the transfer is not completed yet. 

     

  • I also want to ask,

    What does transfer completed mean? İs it that CPU command which includes paRam settings, src adress dst adress, etc...,is transfered to EDMA controller or that the all data transfer is completed from src to dst? According to the results I obtained so far, it is the first one,  becuse there is no time difference between 512 byte data transfer and 8192 byte data transfer. Two of them waits for same time.

    Are there a configuration command for that setting and how can I say to my DSP to wait until all data is tranfered from src to dst?

     

  • What you use as the "waitId" also decides when that ACPY3_wait returns. I'm quoting from the link I shared earlier:-

    • waitId of -1 can be passed in the ACPY3_Params to indicate that no intermediate waits will be made on this linked transfer. Use this in your ACPY3_Params for intermediate transfers that you don't intend to wait on.
    • 0 <= waitId < (numWaits - 1), where numWaits is the parameters you supplied in IDMA3_ChannelRec when creating the IDMA3 handle, can be passed to ACPY3_Params to indicate that this intermediate transfer can be "waited" on by an ACPY3_waitLinked() call.
    • For a single transfer configured (using ACPY3_configure()) or for the last transfer in a series of linked transfers, internally a waitId of (numWaits -1) is automatically used. Any supplied waitId will be ignored. Do not use this waitId for any intermediate transfers.
    Assuming you HAVE set the correct waitId to wait on the completion of the final transfer, the ACPY3_wait API unblocks only when the corresponding IPR register bit is set, and that happens only on the completion of the transfer.

    If you have set everything correctly, but are still observing something different, one culprit could be simply cache. If your DMA-destination is external memory, maybe you need to look at the un-cached view of the memory, could that be the issue ?