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.

EDMA Complete Interrupts in C6457

Hello, we use 2 EDMA3 for data exchange in C6457, one for receive and the other for transmit. We use region 0 for Rx EDMA and region 1 for Tx EDMA. Both EDMA complete interrupts are enabled. Rx EDMA and Tx EDMA are triggered one at a time (not simultaneously). However, either one of the EDMAs will generate both region 0 and region 1 EDMA complete interrups. The correct scenario should be only interrupt event flag 71 is set (region 0) when Rx EDMA is completed and only event flag 72 is set (region 1) when Tx EDMA is finished. Now, both 71 and 72 are set when only one EDMA is completed.

Is there anything wrong in our design? Any suggestion?

Thanks.

  • Have you configured the DRAE registers correctly?

  • Brad, this is our  code to config region 0, region 1 is configed using the same fashion. Is there anything wrong or missing here? Thanks.

     

     

     

     

     

     

     

     

     

     

     

     

     

    // Module Initialization

    statusEdma = CSL_edma3Init(&contextEdma);

     

     

     

    // Module level open

    hModule = CSL_edma3Open(&edmaObj,CSL_EDMA3,

     

    NULL

    ,&statusEdma);

     

     

     

    /* Module setup */

    dmahwSetup.paramNum = 0;

    dmahwSetup.que = CSL_EDMA3_QUE_0;

    hwSetup.dmaChaSetup = &dmahwSetup;

    hwSetup.qdmaChaSetup =

    NULL;

    statusEdma = CSL_edma3HwSetup(hModule,&hwSetup);

     

     

     

    // DRAE enable(Bits 0-15) for the shadow region 0

    regionAccess.region = CSL_EDMA3_REGION_0 ;

    regionAccess.drae = 0xFFFF;

    regionAccess.draeh = 0x0;

    statusEdma = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_DMAREGION_ENABLE, &regionAccess);

     

     

     

    // Channel 0 open in context of shadow region 0

    chAttr.regionNum = CSL_EDMA3_REGION_0;

    chAttr.chaNum = 0;

     

    //CSL_EDMA3_CHA_GPINT1;

    hChannel = CSL_edma3ChannelOpen(&chObj, CSL_EDMA3, &chAttr, &statusEdma);

     

     

     

    /* Obtain a handle to parameter set 0 */

    hParamBasic = CSL_edma3GetParamHandle(hChannel,0,&statusEdma);

     

     

     

    /* Setup the first param set */

    myParamSetup.option = CSL_EDMA3_OPT_MAKE (CSL_EDMA3_ITCCH_DIS, \

    CSL_EDMA3_TCCH_DIS, \

    CSL_EDMA3_ITCINT_DIS, \

    CSL_EDMA3_TCINT_EN,\

    0, CSL_EDMA3_TCC_NORMAL,\

    CSL_EDMA3_FIFOWIDTH_NONE, \

    CSL_EDMA3_STATIC_EN, \

    CSL_EDMA3_SYNC_AB, \

    CSL_EDMA3_ADDRMODE_INCR, \

    CSL_EDMA3_ADDRMODE_INCR

    );

     

    myParamSetup.srcAddr = FPGA_FFT_ADDR0;

    myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(FPGA_FFT_LEN<<2,1);

    myParamSetup.dstAddr = (Uint32)dstBuff0;

    myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(0,0);

    myParamSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(CSL_EDMA3_LINK_NULL,0);

    myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0, 1);

    myParamSetup.cCnt = 1;

    statusEdma = CSL_edma3ParamSetup(hParamBasic, &myParamSetup);

     

     

     

    /* Clear event */

    CSL_intcEventClear(CSL_INTC_EVENTID_EDMA3CC_INT0);

     

     

     

    // Clear interrupt bit 0, moved here from DMA done interrupt by Jun

    regionIntr.region = CSL_EDMA3_REGION_0;

    regionIntr.intr = 0xFFFF;

    regionIntr.intrh = 0xFFFF;

    statusEdma = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTRPEND_CLEAR, &regionIntr);

     

     

     

    /* Enable interrupts */

    regionIntr.region = CSL_EDMA3_REGION_0 ;

    regionIntr.intr = 0xFFFF;

    regionIntr.intrh = 0xFFFF;

     

     

    statusEdma = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTR_ENABLE,&regionIntr);

  • Can you please show exactly what you change for region 1?  It would be best/easiest if you could zip two C files and attach them (click on the "Options" link).  That way I can use a diff tool to quickly/easily see precisely what you changed and make sure it's correct.  Specifically you need to make sure that each channel is "owned" by only a single region, otherwise you'll get interrupts in both.

  • This may be helpful, but if not I understand.

    An alternative to using the 2 regions for the 2 interrupts is to use an Edma3 Interrupt Dispatcher to allow you to have two different ISRs depending on the IPR bit that gets set. The attached CCS 3.3 CSL project was designed specifically for the C6455, but it may be very similar for the C6457 and may work without any changes.

    This project has a fairly simple main.c that sets up two EDMA3 interrupts and two EDMA3 channels, using the Global region for both. The EdmaIntDIspatcher.c file has the hook function for adding ISRs for other IPR bits and the dispatcher ISR itself. Brad and I confered on the updates to the EdmaIntDispatcher.c/h files earlier this year to fix potential functionality and performance issues in the example version that comes with the CSL examples.

    You can get a small performance boost by using the regions, mainly by avoiding the dispatcher function. But the simplicity is better, in my opinion, and the flexibility and maintainability are better, too.

    Regards,
    RandyP

    C6455_Edma.zip
  • Brad, attached is our test code. We do use channel 0 for both regions. That may be the source of the probelm. We tried other channels, but didn't work. Please also help us to check anything wrong on channel configuration in the attached file. Thanks!

     

    FrontEnd_Test_Main.rar
  • Thank you for the help! I'll try it later.

  • You've configured DRAE incorrectly.  If you don't want the same interrupt to be generated for multiple regions then DRAE bits should be mutually exclusive, i.e. a given DRAE/DRAEH bit should only be set in ONE region.

    In your case I would recommend the following:

    • Region 0: Set DRAE = 1 to configure channel 0 as being associated with this region
    • Region 1: Set DRAE = 2 to configure channel 1 as being associated with this region

    Note that if you want to enable more than one interrupt for a given region then you will need to use the edma dispatcher as Randy has kindly provided.