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.

CSL EDMA3 interrupt problem

I am trying to get interrupts working with an EDMA3 transfer of multiple 512 byte packets.  I have a working solution, starting with some example source code uploaded to  another post (http://e2e.ti.com/support/dsp/c6000_multi-core_dsps/f/639/t/177116.aspx - thank you Steven Ji). 

In my isr, I increment a flag for each completion.  In my main function, I have a loop (for i = 1; i <= numPackets; i++), and within it wait until the flag equals my loop index.  That tells me the isr has completed, and I can start the next transfer.

The following code works, but the "printf" in the waiting for flag loop (at the bottom of the listing) causes a long delay between transfers (90 mS).  If I replace the "printf" with a simple dummy++, I get the first interrupt, then it looks like I'm locked in _CSL_intcNmiDummy() processing an internal exception (EFR.IXF = 1, IERR = 0x18 - Opcode and Resource conflict exception).

My question is, why would the code work when using the "printf" call, but fail so miserably when simply doing an increment?

-----

static void edma_isr_handler (void* handle)
{
 CSL_IntcGlobalEnableState   state;

 CSL_CPINTCHostInterrupt       hostIntr = 40;
 CSL_CPINTCSystemInterrupt     sysIntr = 6;

 /* Clear the CPINTC0 Interrupt */
 CSL_CPINTC_clearSysInterrupt (hnd, sysIntr);

 /* Clear the CorePac Interrupt */
 CSL_intcHwControl (hIntc, CSL_INTC_CMD_EVTCLEAR, NULL);

 /* ISR EVENTUAL TASKS */

 /* Clear the pending bit */
     CSL_edma3HwControl (hModule, CSL_EDMA3_CMD_INTRPEND_CLEAR, &regionIntr);

 /* ****************** */

     flag++;

 /* Enable CPINTC0 Host interrupt (CPINTC output) */
 CSL_CPINTC_enableHostInterrupt (hnd, hostIntr);

 if (CSL_CPINTC_isInterruptPending (hnd))
  CSL_edma3HwControl (hModule, CSL_EDMA3_CMD_INTR_EVAL, &regionIntr);
}


void gem_intc_config (void)
{

 CSL_IntcContext             intcContext;
 CSL_IntcGlobalEnableState   state;
 CSL_IntcObj                 intcObj;
 CSL_IntcParam               vectId;
 CSL_IntcEventHandlerRecord  EventRecord;
 CSL_IntcEventHandlerRecord  EventHandler[30];

 intcContext.eventhandlerRecord = EventHandler;
 intcContext.numEvtEntries      = 10;

 /* Initiate INTC module */
 CSL_intcInit (&intcContext);

 /* Enable NMIs : Non Maskable Interrups*/
     CSL_intcGlobalNmiEnable () ;

 /* Enable global interrupts */
 CSL_intcGlobalEnable (&state);

 /* Open the INTC Module for Vector ID: 4 and Event ID: 29 (C6678) */
        /* Instance 1 (EDMACC1), Core 0 */

 vectId = CSL_INTC_VECTID_4;
 hIntc = CSL_intcOpen (&intcObj, 29, &vectId, NULL);

 /* Register a call-back handler which is invoked when the event occurs. */
 EventRecord.handler = &edma_isr_handler;
 EventRecord.arg = 0;

 CSL_intcPlugEventHandler (hIntc, &EventRecord);

 

 /* Enabling the events. */
 CSL_intcHwControl (hIntc, CSL_INTC_CMD_EVTENABLE, NULL);
}

 


void cp_intc_config (void)
{
 // chip-level INTC0 is for CorePac0~3
 hnd = CSL_CPINTC_open (CSL_CP_INTC_0); // edma3 events are mapped to CPINTC0

 /* Disable all host interrupts. */
 CSL_CPINTC_disableAllHostInterrupt (hnd);

 /* Configure no nesting support in the CPINTC Module. */
 CSL_CPINTC_setNestingMode (hnd, CPINTC_NO_NESTING);

 /* Map System Interrupt 6 (EDMACC GINT) to channel 40 */
 CSL_CPINTC_mapSystemIntrToChannel (hnd, 6, 40);

  /* Map channel 40 to host interrupt 40 */
 //CSL_CPINTC_mapChannelToHostInterrupt (hnd, 40 , 40);

 /* Enable system interrupt 6 */
 CSL_CPINTC_enableSysInterrupt (hnd, 6);

 /* We enable host interrupts. */
 CSL_CPINTC_enableHostInterrupt (hnd, 40);

 /* Enable all host interrupts also. */
 CSL_CPINTC_enableAllHostInterrupt (hnd);
}

void csl_main_test (uint16_t *block_src, uint16_t *block_dst, uint16_t packetSize, uint16_t numPackets)
{
 unsigned int i = 0;

 csl_source = block_src;
 csl_dest = block_dst;
 csl_packet_size = packetSize;
 csl_num_packets = numPackets;

 gem_intc_config ();
 cp_intc_config ();

 flag = 0;
 dummy = 0;

 /* Module initialization   */
     CSL_edma3Init (&context) ;

    /* Open the EDMA Module using the instance number   */
    hModule = CSL_edma3Open (&edmaObj, instNum, NULL, &status);

    /* Channel Open Global      */
    chAttr.regionNum = CSL_EDMA3_REGION_GLOBAL;
    chAttr.chaNum    = channelNum;

    hChannel = CSL_edma3ChannelOpen (&chObj, instNum, &chAttr, &status);

    /* Map the DMA Channel to the appropriate PARAM Block.   */
    CSL_edma3HwChannelSetupParam (hChannel, 1) ;

    /* Obtain a handle to parameter set     */
    hParamBlock1 = CSL_edma3GetParamHandle (hChannel, 1, &status);

    /* Setup the param set         */
    myParamSetup.option = CSL_EDMA3_OPT_MAKE( CSL_EDMA3_ITCCH_DIS, \
                                              CSL_EDMA3_TCCH_DIS, \
                                              CSL_EDMA3_ITCINT_EN, \
                                              CSL_EDMA3_TCINT_EN, \
                                              6, \
                                              CSL_EDMA3_TCC_NORMAL, \
                                              CSL_EDMA3_FIFOWIDTH_NONE, \
                                              CSL_EDMA3_STATIC_EN, \
                                              CSL_EDMA3_SYNC_A, \
                                              CSL_EDMA3_ADDRMODE_INCR, \
                                              CSL_EDMA3_ADDRMODE_INCR
                                             );

    myParamSetup.srcAddr    = (Uint32) csl_source;
    myParamSetup.dstAddr    = (Uint32) csl_dest;
    myParamSetup.aCntbCnt   = CSL_EDMA3_CNT_MAKE (packetSize, numPackets);
    myParamSetup.cCnt       = 1;
    myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE (packetSize, 0);
    myParamSetup.linkBcntrld= CSL_EDMA3_LINKBCNTRLD_MAKE (CSL_EDMA3_LINK_NULL, numPackets);
    myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE (0, 0);

    /* Setup the block1 entry */
    CSL_edma3ParamSetup (hParamBlock1, &myParamSetup);

    /* Interrupt enable for the global region interrupts */
   regionIntr.region = CSL_EDMA3_REGION_GLOBAL;
   regionIntr.intr = (1 << 6);
   regionIntr.intrh = 0;
    CSL_edma3HwControl (hModule, CSL_EDMA3_CMD_INTR_ENABLE, &regionIntr);

 for (i = 1; i <= numPackets; i++)
 {
     /* *************************************************************************** */
     /* Manually trigger the channel 1          */
     /* *************************************************************************** */
  CSL_edma3HwChannelControl (hChannel, CSL_EDMA3_CMD_CHANNEL_SET, NULL);

  while (flag != i)
  {
   printf ("wait for flag\n");
//   dummy++;
  }
 }

 /* Close channel        */
 CSL_edma3ChannelClose (hChannel);

 /* Close EDMA module        */
 CSL_edma3Close (hModule);

}