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, ®ionIntr);
/* ****************** */
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, ®ionIntr);
}
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, ®ionIntr);
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);
}