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.

Problem getting isr callback for tcc for QEDMA

Hi,

I am designing a piece of code that needs to incorporate a callback function when QEDMA'ing some data.  I believe I have everything initialized correctly, and have verified that the DMA is actually working because I see my data placed in my destination buffer that I've set, but my callback function is not being called.  Here is some snippets of my code I have:

Initialization stuff:

Int32Type tcc = EDMA_intAlloc(-1);

 //Check for a valid tcc
 if (tcc != -1)
 {
     emifEdmaConfig.opt = EDMA_OPT_RMK(
                                      EDMA_OPT_PRI_HIGH,
                                      // since we want to burst we need to keep it in WORDS
                                      // remember we have 2 16bit consective registers to read from.
                                      EDMA_OPT_ESIZE_32BIT,
                                      EDMA_OPT_2DS_NO,
                                      EDMA_OPT_SUM_NONE,
                                      EDMA_OPT_2DD_NO,
                                      EDMA_OPT_DUM_INC,
                                      EDMA_OPT_TCINT_YES,
                                      EDMA_OPT_TCC_OF( tcc & 0x0F),
                                      EDMA_OPT_TCCM_OF( (tcc >> 4) & 0x03 ),
                                      EDMA_OPT_ATCINT_DEFAULT,
                                      EDMA_OPT_ATCC_DEFAULT,
                                      EDMA_OPT_PDTS_DEFAULT,
                                      EDMA_OPT_PDTD_DEFAULT,
                                      EDMA_OPT_LINK_YES,
                                      EDMA_OPT_FS_YES );

     emifEdmaConfig.src = (Uint32) RX_FIFO_DATA;
     emifEdmaConfig.idx = EDMA_IDX_OF( 0 );
     emifEdmaConfig.rld = EDMA_RLD_OF( 0 );

  //Hook the "EmifMsgEdmaRxCmpltIsr" operation for when the EDMA transfer completes
  EDMA_intHook(tcc, (EDMA_IntHandler) EmifMsgEdmaRxCmpltIsr);

  // Clear the EDMA complete interrupt
  EDMA_intClear(tcc);
 
  //Enable the interrupt
  EDMA_intEnable(tcc);

}
 else
 {
  LOG_printf(&trace, "FATAL ERROR: Invalid tcc returned from EDMA_intAlloc(). None left?");
 }

 

My callback function:

void EmifMsgEdmaRxCmpltIsr( int tcc )
{
   EDMA_intClear(tcc);
   SEM_ipost(SDTR_EMIF_PCI_isr::emifRxEDMASem);
}

 

My QEDMA code:

emifEdmaConfig.cnt = dataLength;
 emifEdmaConfig.dst = (Uint32) &theMsg->msg[PPMI_MSG_HDR_SIZE_WORDS];

 //Check to make sure there IS a length!
 if (emifEdmaConfig.cnt)
 {
       // QEDMA the data
       EDMA_qdmaConfig(&emifEdmaConfig);
  
       // Wait for EDMA completion (release the CPU for others)
       //Wait only 2ms
       if (SEM_pend (emifRxEDMASem, CLK_countspms()*2) == FALSE)
       {
           LOG_printf(&trace, "ERROR: Timeout on SEM_pend() for EMIF DMA tcc.");
       }
 }
 else
 {
  LOG_printf(&trace, "No data length on EDMAConfig arg!");
 }

 

  • Oh btw, I am using CCS v3.3 and the C6416 chipset.  :)

  • Have you plugged EDMA_intDispatcher into the vector table?  Also, you should should remove EDMA_intClear since that is already handled by EDMA_intDispatcher.

  • Glad to have you back to help Brad!  Thanks! :)

    Sooo...where would I put the EDMA_intDispatcher() call?  It's a void return and void parameter function call.  Am I missing some more initialization code from the above snippet to set up my EDMA?

  • I am not using a HWI to do the EDMA...I'm just trying to get the callback function to be called when the DMA completes.

  • The callback function is ultimately interrupt based.  You need to plug EDMA_intDispatcher into the interrupt vector table, i.e. use a BIOS HWI.  When the transfer completes it triggers an interrupt which then runs EDMA_intDispatcher which then calls the function associated with the CIPR bit that is set, i.e. your callback function.

    A couple other notes:

    • SEM_ipost is deprecated (i.e. discouraged).  Use SEM_post.
    • Since your callback function is being called from within a HWI (i.e. from EDMA_intDispatcher) you must use the interrupt dispatcher in order to call SEM_post.  Otherwise you will "confuse" the BIOS scheduler since it won't "know" that an interrupt has occurred.

    Here are some screenshots for you:

    You will of course need to also enable this corresponding interrupt in the CPU's IER.

    Brad

  • Yes yes yes! 

    I needed to plug the EDMA_intHandler() call to a HWI service to get it to call my function correctly.  I added the HWI for the EDMA_Controller to the tcf file, added that code and all seems good now! 

    Changed the deprecated SEM_ipost() and removed the EDMA_intClear() call too from the isr routine while I was at it.

    Thanks again!  You are a great help!