Hi All, I use C6678 evm, I use the EDMA to move data from MSMC to DDR3. The DMA source address will change, but the destination address is fixed. Every time, move a cif image data. The first time, the data move to destinaton buffer correctly. but the others the data of destination buffer never change. following is my code, please tell the reason if you find the problem.
S32 EdmaInit()
{
CSL_Edma3Context context;
CSL_Status status;
CSL_Edma3Obj edmaObj;
CSL_Edma3ChannelAttr chAttr;
CSL_Edma3ChannelObj chObj;
U32 paramSetId = 0;
U32 i = 0;
/* Module initialization */
if (CSL_edma3Init(&context) != CSL_SOK) // do nothing
{
printf ("Error: EDMA module initialization failed\n");
return -1;
}
/* Module level open */
hModule0 = CSL_edma3Open(&edmaObj,0,NULL,&status);
if ((hModule0 == NULL) || (status != CSL_SOK))
{
printf ("Error: EDMA0 module open failed\n");
return -1;
}
#if 0 // if needed, can open the EDMA1/2 through open this macro
/* Module level open */
hModule1 = CSL_edma3Open(&edmaObj,0,NULL,&status);
if ((hModule1 == NULL) || (status != CSL_SOK))
{
printf ("Error: EDMA0 module open failed\n");
return -1;
}
/* Module level open */
hModule2 = CSL_edma3Open(&edmaObj,0,NULL,&status);
if ((hModule2 == NULL) || (status != CSL_SOK))
{
printf ("Error: EDMA0 module open failed\n");
return -1;
}
#endif
// Clear All IPR/IPRH
REG(0x02701070) = 0xffffffff;
REG(0x02701074) = 0xffffffff;
paramSetId = 0;
for(i = 0; i < 16; i++)
{
/* Open QDMA Channel i */
chAttr.regionNum = CSL_EDMA3_REGION_GLOBAL;
chAttr.chaNum = 16 + i;
hChannel0[i] = CSL_edma3ChannelOpen(&chObj, 0, &chAttr, &status);
if ((hChannel0[i] == NULL) || (status != CSL_SOK))
{
printf ("Error: EDMA channel open failed\n");
return -1;
}
/* Map the QDMA Channel to the ParamSet,Every Channel have 4 ParamSets*/
CSL_edma3HwChannelSetupParam (hChannel0[i], paramSetId);
/* Setup the trigger word for the QDMA Channel. CNT Word is the trigger word*/
CSL_edma3HwChannelSetupTriggerWord(hChannel0[i], CSL_EDMA3_TRIGWORD_CCNT);
/* Get Parameter Entry Handle */
hParam0[i] = CSL_edma3GetParamHandle(hChannel0[i], paramSetId, &status);
paramSetId += 4;
/* Enable Channel */
if (CSL_edma3HwChannelControl(hChannel0[i],CSL_EDMA3_CMD_CHANNEL_ENABLE, NULL) != CSL_SOK)
{
printf ("Error: EDMA channel enable command failed\n");
return -1;
}
/* Mapping channel 0 to event queue 0 */
if (CSL_edma3HwChannelSetupQue(hChannel0[i],CSL_EDMA3_QUE_0) != CSL_SOK)
{
printf("Error: EDMA channel setup queue is failed\n");
return -1;
}
}
return 0;
}
S32 EdmaExit()
{
U32 i = 0;
for(i = 0; i < 16; i++)
{
/* Disable the channel */
CSL_edma3HwChannelControl(hChannel0[i],CSL_EDMA3_CMD_CHANNEL_DISABLE, NULL);
/* Close channel */
if (CSL_edma3ChannelClose(hChannel0[i]) != CSL_SOK)
{
printf("Error: EDMA channel close failed\n");
return -1;
}
}
/* Close EDMA module */
if (CSL_edma3Close(hModule0) != CSL_SOK)
{
printf("Error: EDMA module close failed\n");
return -1;
}
return 0;
}
#define WIDTH 352
#define HEIGHT 288
#define PICSIZEY (WIDTH*HEIGHT)
#define PICNUM
// place the yuvDataBuf in MSMCSRAM and pTmpImg in the DDR3 in my *.cmd file
U8 yuvDataBuf[PICSIZEY*PICNUM];
U8 pTmpImg[PICSIZEY];
U8 *currY;
// Used for test
S32 EdmaTest()
{
CSL_Edma3ParamSetup myParamSetup;
CSL_Edma3CmdIntr regionIntr;
U32 i = 0;
U32 frmNum = 0;
currY = yuvDataBuf;
for(frmNum = 0; frmNum < PICNUM; frmNum++)
{
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 = (Uint32)currY;
myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(PICWIDTH,PICHEIGHT);
myParamSetup.dstAddr = (Uint32)pTmpImg;
myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(PICWIDTH,PICWIDTH);
myParamSetup.linkBcntrld= 0;
myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,0);
myParamSetup.cCnt = 1;
if (CSL_edma3ParamSetup(hParam0[0], &myParamSetup) != CSL_SOK)
{
printf ("Error: EDMA param setup failed\n");
return -1;
}
/* Poll IPR bit */
regionIntr.region = CSL_EDMA3_REGION_GLOBAL;
do {
CSL_edma3GetHwStatus(hModule0,CSL_EDMA3_QUERY_INTRPEND,®ionIntr);
} while (!(regionIntr.intr & 0x1));
/* Clear pending interrupt */
if (CSL_edma3HwControl(hModule0,CSL_EDMA3_CMD_INTRPEND_CLEAR, ®ionIntr) != CSL_SOK)
{
printf ("Error: EDMA clear interrupt pend command failed\n");
return -1;
}
// Check Data
for(i = 0; i < 352*288; i++)
{
if(currY[i] != pTmpImg[i])
{
printf("frmNum:%d EDMA error:%d\n",i);
}
}
currY += PICSIZEY;
}
}
int main(void)
{
EdmaInit();
// readfile 10 CIF picture data to the yuvDataBuf buffer
EdmaTest();
return 0;
}