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.

c6455使用EDMA传输FIFO数据到DDR2

c6455使用EDMA传输FIFO数据到DDR2,存的数据始终不变,数据本来是不断变化的,EMIFA的ce2上的片选也没有被拉低,请问是什么原因?FIFO的源地址应该设定为固定地址还是增量地址?代码如下:

#define DDR2_ADDR (0xE0000000)
#define IMAGE_ADDR (0xA0000000)
#define cnt 200
init_emif()
{

*(int *)PERCFG1 = 0x00000003;
rd_be_en=0;
ce_ext=1;

rsetup=0x2;
rstrobe=0x3;
rhold=0x1;
wsetup=0x2;
wstrobe=0x3;
whold=0x1;
yibu_size=1;

wlatency=0;
rlatency=1;
tongbu_size=1;

yibu=0x00000000+(wsetup<<24)+(wstrobe<<18)+(whold<<15)+(rsetup<<11)+(rstrobe<<5)+(rhold<<2)+yibu_size;
tongbu=0x80000100+(wlatency<<6)+(rlatency<<2)+tongbu_size+(rd_be_en<<10)+(ce_ext<<9);
EMIFA_CE2CFG = tongbu;
EMIFA_CE2CFG = tongbu;
EMIFA_CE3CFG = 0x40080042;
EMIFA_CE4CFG = 0x40080042;
EMIFA_CE5CFG = yibu;

EMIFA_BPRIO = 0x000000FE; /* Enable priority based starvation control SPRU971A sec. 7.2 */

/* Configure DDR for 500MHz operation (sequence is order dependent) */
DDR_SDCFG = 0x00D38822; /* Unlock boot + timing, CAS4, 4 banks, 10 bit column */
DDR_SDRFC = 0x000007A2; /* Refresh */
DDR_SDTIM1 = 0x3EDB4B91; /* Timing 1 */
DDR_SDRIM2 = 0x00A2C722; /* Timing 2 */
DDR_DDRPHYC = 0x00000005; /* PHY read latency for CAS 4 is 4 + 2 - 1 */
DDR_SDCFG = 0x00538822; /* Lock, CAS4, 4 banks, 10 bit column, lock timing */
}

void edma_interrupt_example (void)
{
CSL_Edma3HwSetup hwSetup;
CSL_Edma3Obj edmaObj;
CSL_Edma3ParamHandle hParamBasic;
CSL_Edma3ChannelObj chObj;
CSL_Edma3CmdIntr regionIntr;
CSL_Edma3CmdDrae regionAccess;
CSL_Edma3ChannelHandle hChannel;
CSL_Edma3ParamSetup myParamSetup;
CSL_Edma3Context context;
CSL_Edma3ChannelAttr chAttr;
CSL_Status status;
CSL_Edma3HwDmaChannelSetup dmahwSetup;
Uint32 loopIndex;

Uint16 *srcBuff = (Uint16 *)IMAGE_ADDR;
Uint32 *dstBuff = (Uint32 *)DDR2_ADDR;
Uint16 *led = (Uint16 *)LED_ADDR;
Uint32 evtClr;


init_PLL();
init_emif();
(*led)=0x0001;
initializeADV();

/* Initialize data buffers */
for (loopIndex = 0; loopIndex < cnt; loopIndex++) {
//srcBuff[loopIndex] = loopIndex;
dstBuff[loopIndex] = 3;
//printf("%d\n",dstBuff[loopIndex]);
}

/* Module initialization */
status = CSL_edma3Init(&context);
if (status != CSL_SOK) {
printf ("Edma module initialization failed\n");
return;
}

/* Intc module initialization */
intcContext.eventhandlerRecord = EventHandler;
intcContext.numEvtEntries = 10;
CSL_intcInit(&intcContext);

/* Enable NMIs */
CSL_intcGlobalNmiEnable();

/* Enable global interrupts */
CSL_intcGlobalEnable(&state);

/* Opening a intc handle for edma event */
vectId = CSL_INTC_VECTID_4;
hIntcEdma = CSL_intcOpen (&intcObjEdma, CSL_INTC_EVENTID_EDMA3CC_INT1, \
&vectId , NULL);

/* Edma module open */
hModule = CSL_edma3Open(&edmaObj,CSL_EDMA3,NULL,&status);
if ( (hModule == NULL) || (status != CSL_SOK)) {
printf ("Edma module open failed\n");
return;
}

/* Edma module setup */
dmahwSetup.paramNum = 0;
dmahwSetup.que = CSL_EDMA3_QUE_0;
hwSetup.dmaChaSetup = &dmahwSetup;
hwSetup.qdmaChaSetup = NULL;
status = CSL_edma3HwSetup(hModule,&hwSetup);
if (status != CSL_SOK) {
printf ("Hardware setup failed\n");
CSL_edma3Close (hModule);
return;
}

/* Setup the DRAE masks
* DRAE enable(Bits 0-15) for the shadow region 1.
*/
regionAccess.region = CSL_EDMA3_REGION_1 ;
regionAccess.drae = 0xFFFF ;
regionAccess.draeh = 0x0000 ;
status = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_DMAREGION_ENABLE, \
&regionAccess);
if (status != CSL_SOK) {
printf("Edma region enable command failed\n");
return;
}

/* Channel open */
chAttr.regionNum = CSL_EDMA3_REGION_1;
chAttr.chaNum = CSL_EDMA3_CHA_DSP_EVT;
hChannel = CSL_edma3ChannelOpen(&chObj, CSL_EDMA3, &chAttr, &status);
if ( (hChannel == NULL) || (status != CSL_SOK)) {
printf ("Edma channel open failed\n");
return;
}

/* Get the parameter handle */
hParamBasic = CSL_edma3GetParamHandle(hChannel,0,&status);
if (hParamBasic == NULL) {
printf("Edma get param handle failed\n");
return;
}
/* Edma parameter entry Setup */
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_16BIT, \
CSL_EDMA3_STATIC_DIS, \
CSL_EDMA3_SYNC_A, \
CSL_EDMA3_ADDRMODE_INCR, \
CSL_EDMA3_ADDRMODE_INCR);
myParamSetup.srcAddr = (Uint32)srcBuff;
myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(cnt*2,1);
myParamSetup.dstAddr = (Uint32)dstBuff;
myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(0,0);
myParamSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE (CSL_EDMA3_LINK_NULL,
1);
myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,0);
myParamSetup.cCnt = 1;
status = CSL_edma3ParamSetup(hParamBasic,&myParamSetup);
if (status != CSL_SOK) {
printf ("Edma param setup failed\n");
return;
}

/* Association of an EDMA event handler with the INTC routine */
EventRecord.handler = &eventEdmaHandler;
EventRecord.arg = (void*)(hModule);
CSL_intcPlugEventHandler(hIntcEdma,&EventRecord);

/* Enabling event edma */
CSL_intcHwControl(hIntcEdma,CSL_INTC_CMD_EVTENABLE,NULL);

/* Hook up the EDMA event with an completion code function handler */
EdmaEventHook(1, tcc1Fxn);

/* Enable interrupts */
regionIntr.region = CSL_EDMA3_REGION_1 ;
regionIntr.intr = 0x2 ;
regionIntr.intrh = 0x0 ;
status = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTR_ENABLE,&regionIntr);
if (status != CSL_SOK) {
printf ("Edma interrupt enable command failed\n");
return;
}
/* Manually trigger the channel */
status = CSL_edma3HwChannelControl(hChannel,CSL_EDMA3_CMD_CHANNEL_SET,NULL);
if (status != CSL_SOK) {
printf ("Edma channel set command failed\n");
return;
}

/* Wait for completion */
while (!intFlag);

/* Disable the region 1 access */
regionAccess.region = CSL_EDMA3_REGION_1 ;
regionAccess.drae = 0xFFFF ;
regionAccess.draeh = 0x0000 ;
status = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_DMAREGION_DISABLE, \
&regionAccess);
for (loopIndex = 0; loopIndex < 4; loopIndex++) {
evtClr = ((CSL_IntcRegsOvly)CSL_INTC_0_REGS)->EVTFLAG[loopIndex];
((CSL_IntcRegsOvly)CSL_INTC_0_REGS)->EVTCLR[loopIndex] = evtClr;
}


if (passStatus == 1)
printf ("<<EXAMPLE PASSED>>: Edma Interrupt Example Passed\n");

printf ("=============================================================\n");
/* Clear the all events */


/* Channel close */
status = CSL_edma3ChannelClose(hChannel);
if (status != CSL_SOK) {
printf ("Edma channle close failed\n");
return;
}

/* Edma module close */
status = CSL_edma3Close(hModule);
if (status != CSL_SOK) {
printf ("Edma module close failed\n");
return;
}


return;
}
void tcc1Fxn(void)
{
int i=0;
Uint16 tempData=0;
Uint32 *dstBuff = (Uint32 *)DDR2_ADDR;
for(i=0;i<cnt;i++)
{
tempData=dstBuff[i];
printf("Edma: %X\n",tempData);
}
intFlag = 1;
}

  • FIFO的源地址设为固定地址。

    建议一步步来定位问题:先不用EDMA,确定DSP能正确读写FIFO。再用EDMA方式从片上RAM是否能搬移数据到DDR2。最后再把EDMA源地址设为FIFO,看能否搬移。