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.

GPIO triggered EDMA not happening

I'm having some trouble setting up a DMA transfer to be triggered from a GPIO interrupt on a C6678.  From what I can tell from the example code provided in the MCSDK, as well as the CSL docs and SPRS691E but the event is still not being triggered.  The setup code I'm using is pasted below.

// Variables for configuring the EDMA
	CSL_Edma3Handle        hModule;
	CSL_Edma3Obj           edmaObj;
	CSL_Status             status;
	CSL_Edma3CmdDrae       regionAccess;
	CSL_Edma3ChannelAttr   chAttr;
	CSL_Edma3ChannelObj    chObj;
	CSL_Edma3ChannelHandle hChannel;
	CSL_Edma3ParamHandle   hParamBasic;
	CSL_Edma3ParamSetup    myParamSetup;
	unsigned int           reloadAddress;
	
	CSL_CPINTC_Handle         cpintcHandle;
	
	cpintcHandle = CSL_CPINTC_open (CSL_EDMA3CC_2);

	// Disable all host interrupts.
	CSL_CPINTC_disableAllHostInterrupt(cpintcHandle);

	// Configure no nesting support in the CPINTC Module
	CSL_CPINTC_setNestingMode (cpintcHandle, CPINTC_NO_NESTING);

	// Clear GPINT9 system interrupt number 111
	// We get the interrupt number from Table 7-40 in the 6678
	// data manual at www.ti.com/.../sprs691c.pdf
	CSL_CPINTC_clearSysInterrupt (cpintcHandle, CSL_INTC2_GPINT9);
	
	// Map System Interrupt to Channel
	CSL_CPINTC_mapSystemIntrToChannel(cpintcHandle, CSL_INTC2_GPINT9, DMA_FPGA_RX_EVENT);
	CSL_CPINTC_mapChannelToHostInterrupt(cpintcHandle, DMA_FPGA_RX_EVENT, DMA_FPGA_RX_EVENT);
	CSL_CPINTC_enableHostInterrupt(cpintcHandle, DMA_FPGA_RX_EVENT);

	// Enable GPINT9 system interrupt number 1 on CIC2
	CSL_CPINTC_enableSysInterrupt(cpintcHandle, CSL_INTC2_GPINT9);

	// Enable CIC2_OUT48
	CSL_CPINTC_enableHostInterrupt(cpintcHandle, DMA_FPGA_RX_EVENT);

	CSL_CPINTC_enableAllHostInterrupt(cpintcHandle);

	// Initialize the EDMA3 Module.
	CSL_edma3Init(NULL);

	// Module Level Open
	hModule = CSL_edma3Open(&edmaObj, CSL_EDMA3CC_2, NULL, &status);

	// Enable shadow region access?
	regionAccess.region = CSL_EDMA3_REGION_GLOBAL;
	regionAccess.drae = (0x1 << DMA_FPGA_TX_EVENT);
	regionAccess.draeh = (0x1 << (DMA_FPGA_RX_EVENT - 32));
	CSL_edma3HwControl(hModule, CSL_EDMA3_CMD_DMAREGION_ENABLE, &regionAccess);

	// FPGA RX DMA Configuration. This will be triggered by the 48kHz servo interrupt.
	// Open FPGA RX DMA in context of all regions?
	chAttr.regionNum = CSL_EDMA3_REGION_GLOBAL;
	chAttr.chaNum = DMA_FPGA_RX_EVENT;
	hChannel = CSL_edma3ChannelOpen(&chObj, CSL_EDMA3CC_2, &chAttr, &status);

	// Map the channel to initial PARAM Entry
	CSL_edma3HwChannelSetupParam(hChannel, DMA_FPGA_RX_EVENT);

	// Configure FPGA RX DMA initial PARAM entry
	// Obtain a handle to PARAM Entry
	hParamBasic = CSL_edma3GetParamHandle(hChannel, DMA_FPGA_RX_EVENT, &status);

	// Configure PARAM, corresponding register fields are listed on the right.
	// OPT Register fields
	myParamSetup.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS,                      // ITCCHEN: Intermediate transfer completion chaining disabled
	                                         CSL_EDMA3_TCCH_DIS,                       // TCCHEN: Transfer completion chaining disabled
	                                         CSL_EDMA3_ITCINT_DIS,                     // ITCINTEN: Intermediate transfer completion interrupt disabled
	                                         CSL_EDMA3_TCINT_EN,                       // TCINTEN: Transfer completion interrupt enabled. This allows us to detect when the DMA completes by peering into the IPR.
	                                         DMA_FPGA_RX_EVENT,                        // TCC: Transfer completion code. This specifies which bit in the IPR will be set when the DMA completes.
	                                         CSL_EDMA3_TCC_NORMAL,                     // TCCMODE: Normal transfer complete code mode.
	                                         CSL_EDMA3_FIFOWIDTH_NONE,                 // FWID: Incrementing addressing mode, so no FIFOs
	                                         CSL_EDMA3_STATIC_DIS,                     // STATIC: PARAM set is not static, we will link upon completion.
	                                         CSL_EDMA3_SYNC_AB,                        // SYNCDIM: AB synchronized transfer
	                                         CSL_EDMA3_ADDRMODE_INCR,                  // DAM: Destination address is not static
	                                         CSL_EDMA3_ADDRMODE_INCR);                 // SAM: Source address is not static
	myParamSetup.srcAddr = (Uint32)POS_FBK_COUNT_BASE;                                 // Source address
	myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(sizeof(fpgaReceiveData), 1);            // 31:16, B dimension count. 15:0, A dimension count.
	myParamSetup.dstAddr = (Uint32)&fpgaReceiveData;                                   // Destination address
	myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(0, 0);                               // 31:16, destination B dimension increment. 15:0, source B dimension increment.
	reloadAddress = 0x4000 + 0x20*DMA_FPGA_RX_CHAIN_PARAM;
	myParamSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(reloadAddress, 0);           // 31:16, reload PARAM link. 15:0, B count reload value.
	myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0, 0);                               // 31:16, destination C dimension increment. 15:0, source C dimension increment.
	myParamSetup.cCnt = 1;                                                             // C dimension count

	// Configure the PARAM Entry with the setup information.
	CSL_edma3ParamSetup(hParamBasic, &myParamSetup);

	// Duplicate the above setup for the reload parameter entry.
	// Obtain a handle to PARAM Entry
	hParamBasic = CSL_edma3GetParamHandle(hChannel, DMA_FPGA_RX_CHAIN_PARAM, &status);

	// Configure the PARAM Entry with the setup information.
	CSL_edma3ParamSetup(hParamBasic, &myParamSetup);

	// Enable Channel. This sets the corresponding bit in the EER which allows the corresponding interrupt to trigger the DMA.
	CSL_edma3HwChannelControl(hChannel, CSL_EDMA3_CMD_CHANNEL_ENABLE, NULL);

	// Close channel
	CSL_edma3ChannelClose(hChannel);

In the code above DMA_FPGA_RX_EVENT is defined as CSL_EDMA3CC2_INTC2_OUT48 which is 0x26.  Is there a step I'm missing in this setup or is my host interrupt number incorrect?  If so how would I go about calculating it?

  • Hi,

    Thanks for your post.

    Have you ensured whether GPIO interrupt event no's mapped appropriately to EDMA3CC1 & EDMA3CC2 events for C6678? I think, GPIO interrupt event no's 6 - 13 should be mapped for EDMA3CC1 as well EDMA3CC2 events respectively and kindly validate the same in your code inorder to trigger a GPIO interrupt for setting up a DMA transfer.

    Again, CIC2 input event no's 0 to 7 for GPIO system interrupts should be mapped appropriately for EDMA3CC1 and EDMA3CC2. Kindly ensure this, if any secondary events for EDMA3CC1 and EDMA3CC2 are applicable in your code.

    Kindly refer C6678 datasheet for more details on GPIO interrupt event mapping to EDMA3CC1 & EDMA3CC2.

    Thanks & regards,

    Sivaraj K

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

    Please click the Verify Answer button on this post if it answers your question

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

  • According to table 7-40 in http://www.ti.com/lit/ds/symlink/tms320c6678.pdf?deDup422809=1&deDup328893=1 GPINT9 is a secondary input for CIC2.  I believe the problem I'm having is related to mapping the secondary input to the CIC2 input as I can't figure out the correct channel number for it.

  • Hi,

    GPINT9 system interrupt is mapped to input event no. 1 on CIC2 for EDMA3CC1 & EDMA3CC2 and mapped to input event no. 9 on CIC3 for EDMA3CC0. Again, GPINT9 corepac primary interrupt is mapped to system input event no. 83.

    Kindly walkthrough the code and check which DMA channel is being triggered by the peripheral event mapped for EDMA3CC1, EDMA3CC2 or EDMA3CC0 and from which, you could identify the correct DMA channel number to map the secondary input to the CIC2.

    Thanks & regards,

    Sivaraj K

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

    Please click the Verify Answer button on this post if it answers your question

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

  • Sivaraj Kuppuraj said:

    GPINT9 system interrupt is mapped to input event no. 1 on CIC2 for EDMA3CC1 & EDMA3CC2 and mapped to input event no. 9 on CIC3 for EDMA3CC0. Again, GPINT9 corepac primary interrupt is mapped to system input event no. 83.

    Correct, which is why in my code calls the CSL_CPINTC_mapSystemIntrToChannel() function to map System Interrupt CSL_INTC2_GPINT9 (defined as 0x1) to channel CSL_EDMA3CC2_INTC2_OUT48 (defined as 0x26).  My problem isn't finding the correct System Interrupt, it's finding the channel and host interrupt number that can be mapped to the System Interrupt.  Because GPINT9 is not listed in Table 7-37 EDMA3CC2 Events for C6678 I assume it has to be mapped to one of the CIC2_OUTx events.  Am I incorrect in assuming this?  I've gone over the datasheet and the example code several times and can't find a helpful description of how to determine the channel/host interrupt number to map to.

    Sivaraj Kuppuraj said:

    Kindly walkthrough the code and check which DMA channel is being triggered by the peripheral event mapped for EDMA3CC1, EDMA3CC2 or EDMA3CC0 and from which, you could identify the correct DMA channel number to map the secondary input to the CIC2.

    How would I go about which finding which DMA channel is being triggered?

  • Hi,

    I am clear on your interrupt mapping(DMA_FPGA_RX_EVENT) on your above code, please share the full source code. Also refer the keystone interrupt configuration wiki link for mapping system interrupt to channel interrupt.

    Thanks,

  • Hey,

    My EDMA mapping code is currently integrated into the final product software, so posting the full source code isn't feasible.  Is there any specific code you're looking for?  Additionally, I did try using the wiki page you linked as a reference, but didn't find it helpful for mapping to EDMA generic host interrupts as the explanations and example code only reference explicit host interrupts and channels, and the EDMA is only briefly referenced at the beginning.

  • Just to clarify what you ask – looking at http://www.ti.com/lit/ds/symlink/tms320c6678.pdf?deDup422809=1&amp;deDup328893=1

     I am a little confused what is the question now:

    1.  You know which GPIO you want to use and you know how this GPIO is connected to the Interrupt controller input (This is table 7-38 7-39 or 7-40 depends what CIC you use)
    2.  You know which interrupt controller output is connected to EDMA – (this is in tables 7-35 7-36 and 7-37 depends what EDMA controller you want to use)
    3.  You know how to map input event of CIC into output event (If not, I can send you information but I think that you know)
    4.  To trigger EDMA transfer from a signal you need to read http://www.ti.com/lit/ug/sprugs5b/sprugs5b.pdf look for example at 4.2.6.1

    Which of the above is not clear yet?

    Thanks   Ran

  • 1. That's correct, I can determine from 7-40 that for CIC2 I want the GPINT9 input event #.  In my case this is 1.

    2. This is where I'm having an issue.  By referencing 7-37 for CIC2 I see that event numbers 0-37 and 40-41 are all dedicated to specific interrupt controller inputs.  This leaves 38-39 and 42-63 as generic events designated as CIC2_OUTx.  For CIC0 and CIC1, there are several references to equations that are used to determine which interrupt controller inputs map to the CIC_OUTy events, but I can't find an equivalent equation for CIC2.  Can I map the GPINT9 interrupt controller input to any CIC2_OUTx event that is listed in Table 7-37 or are there specific mappings that I need to follow?

  • Hi Keith

    If I understand your issue the answer is that it does not matter which signal you use.  To illustrate the point look at the attached presentation (even though it does not talk about EDMA but you can do the extrapolation) and look at slides 22, 23, 24 and 31. 

    If you still have issue get back to me

    Regards   Ran

  • Ran,

    I have referenced the attached presentation and triple-checked my work, but I'm still not seeing any result from the EDMA.  The code I'm working from is below.

    // Variables for configuring the EDMA
    		CSL_Edma3Handle        hModule;
    		CSL_Edma3Obj           edmaObj;
    		CSL_Status             status;
    		CSL_Edma3CmdDrae       regionAccess;
    		CSL_Edma3ChannelAttr   chAttr;
    		CSL_Edma3ChannelObj    chObj;
    		CSL_Edma3ChannelHandle hChannel;
    		CSL_Edma3ParamHandle   hParamBasic;
    		CSL_Edma3ParamSetup    myParamSetup;
    		unsigned int           reloadAddress;
    
    		// CTRL-27066 - Variables for configuring the CPINTC
    		// System interrupt 0 corresponds to GPINT9 in "Table 7-39 CIC2 Event Inputs" &
    		// Channel 38 corresponds to CIC2_OUT48 in "Table 7-37 EDMA3CC2 Events"
    		// in the C6678 datasheet
    		CSL_CPINTC_Handle         cpintcHandle;
    	
    		cpintcHandle = CSL_CPINTC_open (CSL_EDMA3CC_2);
    
    		// Disable all host interrupts.
    		CSL_CPINTC_disableAllHostInterrupt(cpintcHandle);
    
    		// Configure no nesting support in the CPINTC Module
    		CSL_CPINTC_setNestingMode (cpintcHandle, CPINTC_NO_NESTING);
    
    		// Clear GPINT9 system interrupt number 111
    		// We get the interrupt number from Table 7-40 in the 6678
    		// data manual at www.ti.com/.../sprs691c.pdf
    		CSL_CPINTC_clearSysInterrupt (cpintcHandle, CSL_INTC2_GPINT9);
    	
    		// Map System Interrupt to Channel
    		CSL_CPINTC_mapSystemIntrToChannel(cpintcHandle, CSL_INTC2_GPINT9, DMA_FPGA_RX_EVENT);
    		//CSL_CPINTC_mapChannelToHostInterrupt(cpintcHandle, DMA_FPGA_RX_EVENT, DMA_FPGA_RX_EVENT);
    
    		// Enable GPINT9 system interrupt number 1 on CIC2
    		CSL_CPINTC_enableSysInterrupt(cpintcHandle, CSL_INTC2_GPINT9);
    
    		// Enable CIC2_OUT48
    		CSL_CPINTC_enableHostInterrupt(cpintcHandle, DMA_FPGA_RX_EVENT);
    
    		CSL_CPINTC_enableAllHostInterrupt(cpintcHandle);
    
    		// Initialize the EDMA3 Module.
    		CSL_edma3Init(NULL);
    
    		// Module Level Open
    		hModule = CSL_edma3Open(&edmaObj, CSL_EDMA3CC_2, NULL, &status);
    
    		// Enable shadow region access?
    		regionAccess.region = CSL_EDMA3_REGION_GLOBAL;
    		regionAccess.drae = (0x1 << DMA_FPGA_TX_EVENT);
    		regionAccess.draeh = (0x1 << (DMA_FPGA_RX_EVENT - 32));
    		CSL_edma3HwControl(hModule, CSL_EDMA3_CMD_DMAREGION_ENABLE, &regionAccess);
    
    		// FPGA RX DMA Configuration. This will be triggered by the 48kHz servo interrupt.
    		// Open FPGA RX DMA in context of all regions?
    		chAttr.regionNum = CSL_EDMA3_REGION_GLOBAL;
    		chAttr.chaNum = DMA_FPGA_RX_EVENT;
    		hChannel = CSL_edma3ChannelOpen(&chObj, CSL_EDMA3CC_2, &chAttr, &status);
    
    		// Map the channel to initial PARAM Entry
    		CSL_edma3HwChannelSetupParam(hChannel, DMA_FPGA_RX_EVENT);
    
    		// Configure FPGA RX DMA initial PARAM entry
    		// Obtain a handle to PARAM Entry
    		hParamBasic = CSL_edma3GetParamHandle(hChannel, DMA_FPGA_RX_EVENT, &status);
    
    		// Configure PARAM, corresponding register fields are listed on the right.
    		// OPT Register fields
    		myParamSetup.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS,                      // ITCCHEN: Intermediate transfer completion chaining disabled
    		                                         CSL_EDMA3_TCCH_DIS,                       // TCCHEN: Transfer completion chaining disabled
    		                                         CSL_EDMA3_ITCINT_DIS,                     // ITCINTEN: Intermediate transfer completion interrupt disabled
    		                                         CSL_EDMA3_TCINT_EN,                       // TCINTEN: Transfer completion interrupt enabled. This allows us to detect when the DMA completes by peering into the IPR.
    		                                         DMA_FPGA_RX_EVENT,                        // TCC: Transfer completion code. This specifies which bit in the IPR will be set when the DMA completes.
    		                                         CSL_EDMA3_TCC_NORMAL,                     // TCCMODE: Normal transfer complete code mode.
    		                                         CSL_EDMA3_FIFOWIDTH_NONE,                 // FWID: Incrementing addressing mode, so no FIFOs
    		                                         CSL_EDMA3_STATIC_DIS,                     // STATIC: PARAM set is not static, we will link upon completion.
    		                                         CSL_EDMA3_SYNC_AB,                        // SYNCDIM: AB synchronized transfer
    		                                         CSL_EDMA3_ADDRMODE_INCR,                  // DAM: Destination address is not static
    		                                         CSL_EDMA3_ADDRMODE_INCR);                 // SAM: Source address is not static
    		myParamSetup.srcAddr = (Uint32)POS_FBK_COUNT_BASE;                                 // Source address
    		myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(sizeof(fpgaReceiveData), 1);            // 31:16, B dimension count. 15:0, A dimension count.
    		myParamSetup.dstAddr = (Uint32)&fpgaReceiveData;                                   // Destination address
    		myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(0, 0);                               // 31:16, destination B dimension increment. 15:0, source B dimension increment.
    		reloadAddress = 0x4000 + 0x20*DMA_FPGA_RX_CHAIN_PARAM;
    		myParamSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(reloadAddress, 0);           // 31:16, reload PARAM link. 15:0, B count reload value.
    		myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0, 0);                               // 31:16, destination C dimension increment. 15:0, source C dimension increment.
    		myParamSetup.cCnt = 1;                                                             // C dimension count
    
    		// Configure the PARAM Entry with the setup information.
    		CSL_edma3ParamSetup(hParamBasic, &myParamSetup);
    
    		// Duplicate the above setup for the reload parameter entry.
    		// Obtain a handle to PARAM Entry
    		hParamBasic = CSL_edma3GetParamHandle(hChannel, DMA_FPGA_RX_CHAIN_PARAM, &status);
    
    		// Configure the PARAM Entry with the setup information.
    		CSL_edma3ParamSetup(hParamBasic, &myParamSetup);
    
    		// Enable Channel. This sets the corresponding bit in the EER which allows the corresponding interrupt to trigger the DMA.
    		CSL_edma3HwChannelControl(hChannel, CSL_EDMA3_CMD_CHANNEL_ENABLE, NULL);
    
    		// Close channel
    		CSL_edma3ChannelClose(hChannel);

    I have defined DMA_FPGA_RX_EVENT as both 38 (using the CSL_EDMA3CC2_INTC2_OUT48 define from the CSL) and 48 (corresponding to the output number) as implied by the PowerPoint you attached.

  • So now is the time to start debug and see where we lose the interrupt. You want to follow the interrupt from the GPIO through all the way to the EDMA. The first thing after generating a GPIO interrupt is to look at the System Interrupt Stat
    us Raw/Set Register (see www.ti.com/.../sprugw4a.pdf 2.2.11 and look at the device to see what registers are used and what are their addresses)
    Next you want to see if the interrupt is set at the output of the CIC and the input of the EDMA. Fine the EDMA register that is connected to the output of the CIC and see if it is set. look at www.ti.com/.../sprugs5b.pdf at 4.2.6.3 and identify which bit should be set and see if this bit is set.

    Based on your observations until now you may already know what is wrong. Depends on what is wrong you can check on the CIC mapping registers and so on. Please share with us what have you fond

    Thanks

    Ran
  • I've had one of our other developers go over my code to verify that all of my steps are correct. As it turns out, he noticed that while I was settings up the interrupt correctly, I wasn't clearing it, so it only triggered once. Being that the interrupt is supposed to occur at 1Khz, I was only looking for this periodic occurrence and missed the first and only interrupt. The problem has been resolved now. Thank you for all of your help!