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.

关于EDMA3 PingPong传输的问题

各位专家好!

我在编写EDMA PingPong传输的测试程序时,Ping参数和Pong参数的设置如下所示,由于设置了两个源缓冲区srcBuff1srcBuff2和对应的两个目的缓冲区dstBuff1dstBuff2,所以在传输的时候srcBuff1中的数据往dstBuff1里传送,srcBuff2的数据往dstBuff2里传送

/***************************设置ping参数****************************************/

 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_DIS, \
                                             CSL_EDMA3_SYNC_A, \
                                             CSL_EDMA3_ADDRMODE_INCR, \
                                             CSL_EDMA3_ADDRMODE_INCR );
    myParamSetup.srcAddr    = (Uint32)srcBuff1;
    myParamSetup.aCntbCnt   = CSL_EDMA3_CNT_MAKE(256,1);
    myParamSetup.dstAddr    = (Uint32)dstBuff1;
    myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(1,1);
    myParamSetup.linkBcntrld= CSL_EDMA3_LINKBCNTRLD_MAKE(hParamPong,0);//ping的参数链接地址是Pong的参数,只传输一帧数据,故下一块的ccnt为0
    myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,1);
    myParamSetup.cCnt = 1;

    /* Ping setup*/
    CSL_edma3ParamSetup(hParamPing,&myParamSetup);
   

/***************************设置pong参数****************************************/

    myParamSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(hParamPing,0);//pong的参数链接地址是Ping的参数,只传输一帧数据,故下一块的ccnt为0
    myParamSetup.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, \
                                             CSL_EDMA3_TCCH_DIS, \
                                             CSL_EDMA3_ITCINT_DIS, \
                                             CSL_EDMA3_TCINT_EN,\
                                             1, 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)srcBuff2;
    myParamSetup.dstAddr = (Uint32)dstBuff2;

    /* Pong setup */
    CSL_edma3ParamSetup(hParamPong,&myParamSetup);

现在我需要将数据从一个外设往内存里面传输,希望只设置一个源缓冲区,而设置两个目的缓冲区,交替往两个目的缓冲区里传输数据,问题是,如果按照我上面的方法设置参数的话,由于PingPong两组参数通过link相互链接,这样会导致数据往一个目的缓冲区传输以后又往另一个目的缓冲区重新传输一遍,但我希望的是将其中一个目的缓冲区装满以后,继续将源缓冲区剩下的数据往另一个目的缓冲区传送,而不是重复传送同样的数据,请问应该怎么样设置参数呢?谢谢!

  • Hi, Andy,

    按照你的需求,如果需要从一个源缓冲区向两个地址传送数据,那么你还是需要设置两组参数并且确定每组参数的源和目标地址,传输长度,等等,你可以考虑通过chain或者self-chain的方式将这两个传输链接在一起。这里有一个例子供你参考。


    /*
     * =============================================================================
     *   @func  edma_chain_example
     * 
     *   @arg
     *      NONE
     *
     *   @desc
     *      This is the example routine which perform edma interrupt.
     *      It implements following steps
     *          1. Intializes and Opens the Edma
     *          2. Sets up the edma module using the API csl_edma3Hwsetup ()
     *          4. Enables the edma region5 using CSL_EDMA3_CMD_DMAREGION_ENABLE.
     *          5. Opens the channel 0 and get the param handle.
     *          6. Sets up the edma param entry for channel 0
     *          7. Opens the channel 8 and get the param handle.
     *          8. Sets up the edma param entry  for channel 8
     *          9. Enables the channels using CSL_EDMA3_CMD_CHANNEL_ENABLE
     *          10. Manually trigger the channel 0 using CSL_EDMA3_CMD_CHANNEL_SET.
     *          10. Waits for transfer to complete.
     *          11. Compares the data in the destination buffer is proper or not.
     *          12. Closes the edma module and channel.
     *
     *   @return
     *      NONE
     *
     * =============================================================================
     */
    void edma_chain_example (void)
    {
        CSL_Edma3Handle             hModule;
    //    CSL_Edma3HwSetup            hwSetup;
        CSL_Edma3Obj                edmaObj;
        CSL_Edma3ParamHandle        hParamBasic;
        CSL_Edma3ParamHandle        hParamBasic1;
        CSL_Edma3ChannelObj         chObj;
        CSL_Edma3ChannelObj         chObj1, chObj2;
        CSL_Edma3CmdIntr            regionIntr;
        CSL_Edma3CmdDrae            regionAccess;
        CSL_Edma3ChannelHandle      hChannel;
        CSL_Edma3ChannelHandle      hChannel1, hChannel2;
        CSL_Edma3ParamSetup         myParamSetup;
        CSL_Edma3ParamSetup         myParamSetup1;
        CSL_Edma3Context            context;
        CSL_Edma3ChannelAttr        chAttr;
        CSL_Edma3ChannelAttr        chAttr1, chAttr2;
        CSL_Status                  status;
       
    // CSL_Edma3HwDmaChannelSetup dmahwSetup[CSL_EDMA3_NUM_DMACH] =
    //         CSL_EDMA3_DMACHANNELSETUP_DEFAULT;
    // CSL_Edma3HwQdmaChannelSetup qdmahwSetup[CSL_EDMA3_NUM_QDMACH] =
    //         CSL_EDMA3_QDMACHANNELSETUP_DEFAULT;
        volatile Uint32             loopIndex;

       
        printf ("Running Edma Example\n");
       
        /* Module Initialization */
        status = CSL_edma3Init(&context);
        if (status != CSL_SOK) {
            printf ("Edma module initialization failed\n");  
            return;
        }
       
        /* Module level open */
        hModule = CSL_edma3Open(&edmaObj,CSL_EDMA3,NULL,&status);
        if ( (hModule == NULL) || (status != CSL_SOK)) {
            printf ("Edma module open failed\n");   
            return;
        }
    #if 0   
        /* Module setup */
        dmahwSetup[CSL_EDMA3_CHA_TEVTLO0].paramNum = CSL_EDMA3_CHA_TEVTLO0;
        dmahwSetup[CSL_EDMA3_CHA_TEVTLO0].que = CSL_EDMA3_QUE_0;
        dmahwSetup[CSL_EDMA3_CHA_CIC3_EVT2].paramNum = CSL_EDMA3_CHA_CIC3_EVT2;
        dmahwSetup[CSL_EDMA3_CHA_CIC3_EVT2].que = CSL_EDMA3_QUE_0;
        hwSetup.dmaChaSetup = &dmahwSetup[0];
        hwSetup.qdmaChaSetup = &qdmahwSetup[0];
        status = CSL_edma3HwSetup(hModule,&hwSetup);
        if (status != CSL_SOK) {
             printf ("Hardware setup failed\n");
             CSL_edma3Close (hModule);
             return;
        }
    #endif     
        /* DRAE enable(Bits 0-15) for the shadow region 5 */
        regionAccess.region = CSL_EDMA3_REGION_5 ;
        regionAccess.drae =   (1 << CSL_EDMA3_CHA_TEVTLO0)
              |(1 << CSL_EDMA3_CHA_CIC3_EVT2)
              |(1 << CSL_EDMA3_CHA_TEVTHI1);  
        regionAccess.draeh = 0;
        status = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_DMAREGION_ENABLE, \
                                   &regionAccess);
        if (status != CSL_SOK) {
            printf ("Edma region enable command failed\n");
            return;
        }

        /* Channel 0 open in context of shadow region 5 */
        chAttr.regionNum = CSL_EDMA3_REGION_5;
        chAttr.chaNum = CSL_EDMA3_CHA_TEVTLO0;
        hChannel = CSL_edma3ChannelOpen(&chObj, CSL_EDMA3, &chAttr, &status);  
        if ((hChannel == NULL) || (status != CSL_SOK)) {
            printf ("Edma channel open failed\n");
            return;
        }
       

     CSL_edma3HwChannelSetupParam(hChannel, CSL_EDMA3_CHA_TEVTLO0);
        if (status != CSL_SOK) {
            printf ("Edma channel setup param failed\n");   
            return;
        }

        /* Change Channel Default queue setup to 0 */
        status = CSL_edma3HwChannelSetupQue(hChannel,CSL_EDMA3_QUE_0);
        if (status != CSL_SOK) {
            printf ("Edma channel setup que failed\n");   
            return;
        }
      
        /* Obtain a handle to parameter set 0 */
        hParamBasic = CSL_edma3GetParamHandle(hChannel,0,NULL);
        if (hParamBasic == NULL) {
            printf ("Edma get param handle for param entry 0 failed\n");   
            return;
        }
       
        /* Setup the param set */
        myParamSetup.option = CSL_EDMA3_OPT_MAKE( CSL_EDMA3_ITCCH_DIS, \
                                                  CSL_EDMA3_TCCH_EN, \
                                                  CSL_EDMA3_ITCINT_DIS, \
                                                  CSL_EDMA3_TCINT_EN,\
                                                  CSL_EDMA3_CHA_CIC3_EVT2,
                                                  CSL_EDMA3_TCC_NORMAL,\
                                                  CSL_EDMA3_FIFOWIDTH_NONE, \
                                                  CSL_EDMA3_STATIC_DIS, \
                                                  CSL_EDMA3_SYNC_AB, \
                                                  CSL_EDMA3_ADDRMODE_INCR, \
                                                  CSL_EDMA3_ADDRMODE_INCR
                                                 );          
        myParamSetup.srcAddr = (Uint32)srcBuff1;        
        myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(512,1);
        myParamSetup.dstAddr = (Uint32)dstBuff1;       
        myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(512,512);    
        myParamSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(CSL_EDMA3_LINK_NULL,0);    
        myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,1);    
        myParamSetup.cCnt = 1;

        status = CSL_edma3ParamSetup(hParamBasic, &myParamSetup);
        if (status != CSL_SOK) {
            printf("Edma parameter entry setup is failed\n");
            return;
        }
       
         /* Channel 8 open in context of shadow region 5 */
        chAttr1.regionNum = CSL_EDMA3_REGION_5;
        chAttr1.chaNum = CSL_EDMA3_CHA_CIC3_EVT2;
        hChannel1 = CSL_edma3ChannelOpen(&chObj1, CSL_EDMA3, &chAttr1, &status);  
        if ((hChannel1 == NULL) || (status != CSL_SOK)) {
            printf ("Edma channel open failed\n");
            return;
        }

     CSL_edma3HwChannelSetupParam(hChannel1, CSL_EDMA3_CHA_CIC3_EVT2);
        if (status != CSL_SOK) {
            printf ("Edma channel setup param failed\n");   
            return;
        }

        /* Change Channel Default queue setup to 0 */
        status = CSL_edma3HwChannelSetupQue(hChannel1,CSL_EDMA3_QUE_0);
        if (status != CSL_SOK) {
            printf ("Edma channel setup que failed\n");   
            return;
        }

        /* Channel 8 open in context of shadow region 5 */
        chAttr2.regionNum = CSL_EDMA3_REGION_5;
        chAttr2.chaNum = CSL_EDMA3_CHA_TEVTHI1;
        hChannel2 = CSL_edma3ChannelOpen(&chObj2, CSL_EDMA3, &chAttr2, &status);  
        if ((hChannel2 == NULL) || (status != CSL_SOK)) {
            printf ("Edma channel open failed\n");
            return;
        }

     CSL_edma3HwChannelSetupParam(hChannel2, CSL_EDMA3_CHA_TEVTHI1);
        if (status != CSL_SOK) {
            printf ("Edma channel setup param failed\n");   
            return;
        }

        /* Change Channel Default queue setup to 0 */
        status = CSL_edma3HwChannelSetupQue(hChannel2,CSL_EDMA3_QUE_0);
        if (status != CSL_SOK) {
            printf ("Edma channel setup que failed\n");   
            return;
        }

       
        /* Obtain a handle to parameter set 8 */
        hParamBasic1 = CSL_edma3GetParamHandle(hChannel1,8,NULL);

        /* Setup the param set */ 
        myParamSetup1.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, \
                                                  CSL_EDMA3_TCCH_EN, \
                                                  CSL_EDMA3_ITCINT_DIS, \
                                                  CSL_EDMA3_TCINT_EN, \
                                                  CSL_EDMA3_CHA_TEVTHI1, \
                                                  CSL_EDMA3_TCC_NORMAL, \
                                                  CSL_EDMA3_FIFOWIDTH_NONE, \
                                                  TRUE,CSL_EDMA3_SYNC_AB, \
                                                  CSL_EDMA3_ADDRMODE_INCR, \
                                                  CSL_EDMA3_ADDRMODE_INCR
                                                 );          
        myParamSetup1.srcAddr = (Uint32)srcBuff2;
        myParamSetup1.aCntbCnt = CSL_EDMA3_CNT_MAKE(512,1);
        myParamSetup1.dstAddr = (Uint32)dstBuff2;       
        myParamSetup1.srcDstBidx = CSL_EDMA3_BIDX_MAKE(512,512);    
        myParamSetup1.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(CSL_EDMA3_LINK_NULL,0);    
        myParamSetup1.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,1);    
        myParamSetup1.cCnt = 1;

        status = CSL_edma3ParamSetup(hParamBasic1,&myParamSetup1);
        if (status != CSL_SOK) {
            printf("Edma parameter entry setup is failed\n");
            return;
        }
       
        /* Enable channel 0 */
        status = CSL_edma3HwChannelControl(hChannel,CSL_EDMA3_CMD_CHANNEL_ENABLE, NULL);
        if (status != CSL_SOK) {
            printf("Edma channel enable command for channel 0 is failed\n");
            return;
        }
                                         
        /* Enable channel 8 */
        status = CSL_edma3HwChannelControl(hChannel1,CSL_EDMA3_CMD_CHANNEL_ENABLE, \
                                            NULL);
        if (status != CSL_SOK) {
            printf("Edma channel enable command for channel 8 is failed\n");
            return;
        }
       
        /* Initialize data */
        for (loopIndex = 0; loopIndex < 512; loopIndex++) {
            srcBuff1[loopIndex] = loopIndex;
            srcBuff2[loopIndex] = ~loopIndex;
            dstBuff1[loopIndex] = 0;
            dstBuff2[loopIndex] = 0;       
        }
       
        /* Trigger Channel 0 */
        CSL_edma3HwChannelControl(hChannel,CSL_EDMA3_CMD_CHANNEL_SET,NULL);

        regionIntr.region = CSL_EDMA3_REGION_5;
        do {
            /* Poll on interrupt bit 1 */
            CSL_edma3GetHwStatus(hModule,CSL_EDMA3_QUERY_INTRPEND,&regionIntr);
        } while (!(regionIntr.intr & (1 << CSL_EDMA3_CHA_TEVTHI1)));
       
       
        /* Clear interrupt bits */   
        status = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTRPEND_CLEAR, \
                                  &regionIntr);  
        if (status != CSL_SOK) {
            printf("Edma clear interrupt bits command has failed\n");
            return;
        }
       
        /* Check transfer */
        if(Verify_Transfer(512, 1, 1, 0, 0, 0, 0, srcBuff1, dstBuff1,TRUE) == FALSE)
            passStatus = 0;
        if(Verify_Transfer(512, 1, 1, 0, 0, 0, 0, srcBuff2, dstBuff2,TRUE) == FALSE)
            passStatus = 0;
              
        if (passStatus == 1)   
            printf ("<<EXAMPLE PASSED>>: Edma Chain Transfer Passed\n");
        else {
            printf ("<<EXAMPLE FAILED>>: Edma Chain Transfer Failed\n");
            return;
        }   
       
       
        /* Close channel */
        status = CSL_edma3ChannelClose(hChannel);
        if (status != CSL_SOK) {
            printf("Edma channel close failed\n");
            return;
        }
       
        /* Close edma module */
        status = CSL_edma3Close(hModule);
        if (status != CSL_SOK) {
            printf("Edma module close failed\n");
            return;
        }
       
        printf ("=============================================================\n");
       
        return;
    }

  • Allen Yin

    您给的程序在编译的时候提示如下的错误,请问是什么原因呢?谢谢!

    identifier "CSL_EDMA3_CHA_CIC3_EVT2" is undefined

    identifier "CSL_EDMA3_CHA_TEVTHI1" is undefined

    identifier "CSL_EDMA3_CHA_TEVTLO0" is undefined

    identifier "CSL_EDMA3" is undefined

    identifier "passStatus" is undefined

  • 您好,

    你需要包含CSL_EDMA相关的头文件,并自己定义一下需要的变量,上述给的只是一个C文件。

x 出现错误。请重试或与管理员联系。