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.

QDMA linking PaRam set reset useless?

#include	<stdio.h>

#include	<xdc/std.h>
#include	<xdc/runtime/System.h>
#include	<xdc/runtime/Memory.h>
#include	<xdc/runtime/IHeap.h>
#include	<xdc/runtime/Error.h>

#include	<ti/sysbios/Bios.h>
#include	<ti/sysbios/hal/Hwi.h>
#include	<ti/sysbios/family/c66/Cache.h>
#include	<ti/sysbios/knl/Task.h>
#include	<ti/sysbios/knl/Idle.h>
#include	<ti/sysbios/knl/Semaphore.h>

#include	<ti/csl/csl_edma3.h>
#include	<ti/csl/csl_edma3Aux.h>

#include	<ti/csl/csl_cache.h>
#include	<ti/csl/csl_cacheAux.h>

#include	"QDMAFunc.h"
#include	"ReadBmpImage.h"



CSL_Edma3Handle             hModule_QDMA;
CSL_Edma3Obj                edmaObj_QDMA;
CSL_Edma3ParamHandle        hParam1,hParam2,hParam3;
CSL_Edma3ChannelObj         chObj_QDMA;
CSL_Edma3CmdIntr            regionIntr_QDMA;
CSL_Edma3ChannelHandle      hChannel_QDMA;
CSL_Edma3ParamSetup         myParamSetup_QDMA;
CSL_Edma3Context            context_QDMA;
CSL_Edma3ChannelAttr        chAttr_QDMA;
CSL_Status                  status_QDMA;


//CSL_EDMA3_REGION_GLOBAL;
//����0��ɹ���1Ϊʧ�ܡ�
int QDMAInit()
{
	   /* Module initialization */
	    if (CSL_edma3Init(&context_QDMA) != CSL_SOK)
	    {
	        printf ("Error: EDMA module initialization failed\n");
	        return -1;
	    }

	    /* Module level open */
	    hModule_QDMA = CSL_edma3Open(&edmaObj_QDMA,DDR3InstNum,NULL,&status_QDMA);
	    if ((hModule_QDMA == NULL) || (status_QDMA != CSL_SOK))
	    {
	        printf ("Error: EDMA module open failed\n");
	        return -1;
	    }

	    /* QDMA Channel Open */
	    chAttr_QDMA.regionNum = CSL_EDMA3_REGION_GLOBAL;
	    chAttr_QDMA.chaNum    = Core0QDMAChannelNum;
	    hChannel_QDMA = CSL_edma3ChannelOpen(&chObj_QDMA, DDR3InstNum, &chAttr_QDMA, &status_QDMA);
	    if ((hChannel_QDMA == NULL) || (status_QDMA != CSL_SOK))
	    {
	        printf ("Error: EDMA channel open failed\n");
	        return -1;
	    }

	    //��0~3ӳ�䵽Queue0(Ĭ��)����4~7ӳ�䵽Queue1����ֹevent��ʧ----���Ǵ���ģ�
	    //����Event Queue�����ȼ��������������֣����4~7���¼���Զ�����ᱻ��Ӧ�����ԣ�ͳһ���䵽ijһ��Queue�ϣ�
	    if(!DDR3InstNum)
	    {
	        /* For first EDMA instance there are only 2 TCs and 2 event queues
	         * Modify the channel default queue setup from 0 to 1
	         */
	         if (CSL_edma3HwChannelSetupQue(hChannel_QDMA,CSL_EDMA3_QUE_0) != CSL_SOK)
	        {
	            System_printf ("Error: EDMA channel setup queue failed\n");
	        }
	    }
	    else
	    {
	        /* For EDMA instance 1 and 2 maximum of 4 TCs and 4 event queues are supported
	         * Change Channel Default queue setup from 0 to 3
	         */
	        if (CSL_edma3HwChannelSetupQue(hChannel_QDMA,CSL_EDMA3_QUE_3) != CSL_SOK)
	        {
	            System_printf ("Error: EDMA channel setup queue failed\n");
	        }
	    }

	    /* Map QDMA Channel to the PING Param Block i.e. 1 */
	    CSL_edma3HwChannelSetupParam (hChannel_QDMA, Core0ParamNum1);//EDMAInitTask()EDMA���Ѿ��õ�Param 7�ˣ�

	    //QDMA��trigger wordֻ����0~7֮�䣺0����PaRam��OPT�Ĵ�������������7����PaRam��CCNT�Ĵ�����
	    /* Setup the trigger word for the QDMA Channel. */
	    CSL_edma3HwChannelSetupTriggerWord(hChannel_QDMA, CoreQDMATW);

	    /* Parameter 1 Entry Handle */
	    hParam1 = CSL_edma3GetParamHandle(hChannel_QDMA, Core0ParamNum1, &status_QDMA);
	    if (hParam1 == NULL)
	    {
	        printf ("Error: EDMA get handle for param entry 1 failed\n");
	        return -1;
	    }

	    /* Parameter 2 Entry Handle */
	    hParam2 = CSL_edma3GetParamHandle(hChannel_QDMA, Core0ParamNum2, &status_QDMA);
	    if (hParam2 == NULL)
	    {
	        printf ("Error: EDMA get handle for param entry 2 failed\n");
	        return -1;
	    }

	    /* Parameter 3 Entry Handle */
	    hParam3 = CSL_edma3GetParamHandle(hChannel_QDMA, Core0ParamNum3, &status_QDMA);
	    if (hParam3 == NULL)
	    {
	        printf ("Error: EDMA get handle for param entry 3 failed\n");
	        return -1;
	    }

	    /* Enable Channel */
	    if (CSL_edma3HwChannelControl(hChannel_QDMA,CSL_EDMA3_CMD_CHANNEL_ENABLE, NULL) != CSL_SOK)
	    {
	         printf ("Error: EDMA channel enable command failed\n");
	         return -1;
	    }

	    /* Interrupt enable (Bits 0-2)  for the global region interrupts */
	    regionIntr_QDMA.region = CSL_EDMA3_REGION_GLOBAL;
	    regionIntr_QDMA.intr   = 0x7;
	    regionIntr_QDMA.intrh  = 0x0000;
	    CSL_edma3HwControl(hModule_QDMA,CSL_EDMA3_CMD_INTR_ENABLE,&regionIntr_QDMA);

	    return 0;
}

//����0��ɹ���1Ϊʧ�ܡ�
int DataRead(float* src1,float* src2,float* src3,float* dst1,float* dst2,float* dst3)
{
	int i,j;
	//QDMA��PARAM����ʱ�����Զ�����channel������EDMA���У�������Ҫ���ϲ�ѯ��
	//TCC��0~31����IPR��0~32λ����ʱTCC����Ψһ������ᴥ�������ں˵��ж�/�¼���
	//����TCC���·���--��0��0��1��2����1��0��1��3������������7��0��1��9��
    /* Setup param entry */
    myParamSetup_QDMA.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, \
                                             CSL_EDMA3_TCCH_DIS, \
                                             CSL_EDMA3_ITCINT_DIS, \
                                             CSL_EDMA3_TCINT_DIS,\
                                             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_QDMA.srcAddr    = (Uint32)src1;
    myParamSetup_QDMA.aCntbCnt   = CSL_EDMA3_CNT_MAKE(ImageWidth*sizeof(float),1);
    myParamSetup_QDMA.dstAddr    = (Uint32)dst1;
    myParamSetup_QDMA.srcDstBidx = CSL_EDMA3_BIDX_MAKE(1,1);
    myParamSetup_QDMA.linkBcntrld= CSL_EDMA3_LINKBCNTRLD_MAKE(hParam2,0);
    myParamSetup_QDMA.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,1);
    myParamSetup_QDMA.cCnt       = 1;

    /* Setup PING to operate with this PARAM Entry. */
    if (CSL_edma3ParamSetup(hParam1, &myParamSetup_QDMA) != CSL_SOK)
    {
         printf ("Error: EDMA param setup failed\n");
         return -1;
    }

    /* Setting up the next entry */
    myParamSetup_QDMA.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, \
                                             CSL_EDMA3_TCCH_DIS, \
                                             CSL_EDMA3_ITCINT_DIS, \
                                             CSL_EDMA3_TCINT_DIS,\
                                             1,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_QDMA.srcAddr    = (Uint32)src2;
    myParamSetup_QDMA.aCntbCnt   = CSL_EDMA3_CNT_MAKE(ImageWidth*sizeof(float),1);
    myParamSetup_QDMA.dstAddr    = (Uint32)dst2;
    myParamSetup_QDMA.srcDstBidx = CSL_EDMA3_BIDX_MAKE(1,1);
    myParamSetup_QDMA.linkBcntrld= CSL_EDMA3_LINKBCNTRLD_MAKE(hParam3,0);
    myParamSetup_QDMA.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,1);
    myParamSetup_QDMA.cCnt       = 1;

    /* Setup for the Pong buffer */
    if (CSL_edma3ParamSetup(hParam2,&myParamSetup_QDMA) != CSL_SOK)
    {
         printf ("Error: EDMA param setup failed\n");
         return -1;
    }

    /* Setting up the next entry */
    myParamSetup_QDMA.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, \
                                             CSL_EDMA3_TCCH_DIS, \
                                             CSL_EDMA3_ITCINT_DIS, \
                                             CSL_EDMA3_TCINT_EN,\
                                             2,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_QDMA.srcAddr    = (Uint32)src3;
    myParamSetup_QDMA.aCntbCnt   = CSL_EDMA3_CNT_MAKE(ImageWidth*sizeof(float),1);
    myParamSetup_QDMA.dstAddr    = (Uint32)dst3;
    myParamSetup_QDMA.srcDstBidx = CSL_EDMA3_BIDX_MAKE(1,1);
    myParamSetup_QDMA.linkBcntrld= CSL_EDMA3_LINKBCNTRLD_MAKE(0xffff,0);
    myParamSetup_QDMA.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,1);
    myParamSetup_QDMA.cCnt       = 1;

    /* Setup for the Pong buffer */
    if (CSL_edma3ParamSetup(hParam3,&myParamSetup_QDMA) != CSL_SOK)
    {
         printf ("Error: EDMA param setup failed\n");
         return -1;
    }

    /* Trigger the word by writing to the trigger word... */
    if (CSL_edma3ParamWriteWord(hParam1,CoreQDMATW,1) != CSL_SOK) {
         printf ("Error: EDMA param write word failed\n");
         return -1;
    }

    regionIntr_QDMA.region = CSL_EDMA3_REGION_GLOBAL;
    regionIntr_QDMA.intr   = 0;
    regionIntr_QDMA.intrh  = 0;
    /* Poll IPR bit */
    do {
    	CSL_edma3GetHwStatus(hModule_QDMA,CSL_EDMA3_QUERY_INTRPEND,&regionIntr_QDMA);
    } while (!(regionIntr_QDMA.intr & 0x4));

    /* Clear pending interrupt */
    if (CSL_edma3HwControl(hModule_QDMA,CSL_EDMA3_CMD_INTRPEND_CLEAR, &regionIntr_QDMA) != CSL_SOK)
    {
         printf ("Error: EDMA clear interrupt pend command failed\n");
         return -1;
    }

    return 0;
}

//����0��ɹ���1Ϊʧ�ܡ�
int DataWrite(float* src1,float* dst1)
{
	int i,j;
    /* Setting up the next entry */
    myParamSetup_QDMA.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, \
                                             CSL_EDMA3_TCCH_DIS, \
                                             CSL_EDMA3_ITCINT_DIS, \
                                             CSL_EDMA3_TCINT_EN,\
                                             2,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_QDMA.srcAddr    = (Uint32)src1;
    myParamSetup_QDMA.aCntbCnt   = CSL_EDMA3_CNT_MAKE(ImageWidth*sizeof(float),1);
    myParamSetup_QDMA.dstAddr    = (Uint32)dst1;
    myParamSetup_QDMA.srcDstBidx = CSL_EDMA3_BIDX_MAKE(1,1);
    myParamSetup_QDMA.linkBcntrld= CSL_EDMA3_LINKBCNTRLD_MAKE(0xffff,0);
    myParamSetup_QDMA.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,1);
    myParamSetup_QDMA.cCnt       = 1;

    /* Setup for the Pong buffer */
    if (CSL_edma3ParamSetup(hParam1,&myParamSetup_QDMA) != CSL_SOK)
    {
         printf ("Error: EDMA param setup failed\n");
         return -1;
    }

    /* Trigger the word by writing to the trigger word... */
    if (CSL_edma3ParamWriteWord(hParam1,CoreQDMATW,1) != CSL_SOK) {
         printf ("Error: EDMA param write word failed\n");
         return -1;
    }

    regionIntr_QDMA.region = CSL_EDMA3_REGION_GLOBAL;
    regionIntr_QDMA.intr   = 0;
    regionIntr_QDMA.intrh  = 0;
    /* Poll IPR bit */
    do {
    	CSL_edma3GetHwStatus(hModule_QDMA,CSL_EDMA3_QUERY_INTRPEND,&regionIntr_QDMA);
    } while (!(regionIntr_QDMA.intr & 0x4));

    /* Clear pending interrupt */
    if (CSL_edma3HwControl(hModule_QDMA,CSL_EDMA3_CMD_INTRPEND_CLEAR, &regionIntr_QDMA) != CSL_SOK)
    {
         printf ("Error: EDMA clear interrupt pend command failed\n");
         return -1;
    }

    return 0;
}
4336.QDMAFunc.h

Hello,

         I use QDMA to move 3 different block data  from DDR3 to L1DSRAM by DataRead() and then move back to DDR3 by DataWrite() in TMS320C6678EVM. I was wondering that if a linking PaRam set can reuse because for the first time calling DataRead(),all data moved correctly from DDR3 to L1DSRAM, but when I changed the src & dst address in all the 3 PaRam sets, the first PaRam set's data correctly moved  to the L1DSRAM, but others PaRam sets act as null PaRam sets because data block in L1DSRAM never changed. I calling the function pair a lot of times just as follows:

for (i=0;i<1000;i++)

{

DataRead();

...

DataWrite();

      And, of course , it was stuck in the middle of the loop. I checked the EDMA3_CC0 registers found that bit 0 was set in the QEMR.

     I disabled cache, and changed the L1DSRAM local address to global address. Only core 0 use it.

     I really do not know how could this happened? Really appreciate for you help !

  • Hi,

    yes, the linking PaRAM can be reused.  I took a quick look of your code.  I don't not see anything is wrong.  Is it possible you can simplify your code such as only doing DataRead() in the loop and linking with one PaRAM instead of 2.  You may also want to try DDR->L2 SRAM and DDR->DDR.if see if there is any behavior change and hopeful it can help you to find what's wrong.

    Xiaohui