各位专家好!
在CCS5.4 下调试EDMA3时遇到一个问题,使用demo edma3_drv_bios6_c6678be_st_sample 进行AB模式(二维)下搬移,发现不能达到一次最大传输65535*65535字节长度。具体如下:
一维EDMA搬移时,一次EDMA可以最大搬移65535B,是没有问题的;
2. 在进行二维AB搬移时,我们理解是一次最大可以搬移 65535 * 65535 * 65535个字节,但是实际测试时发现
Acnt* bcnt 不能超出65535B,超出部分搬移不过去。
不知道这个与什么有关,请各位专家帮忙分析下,多谢!
代码如下:
************************
EDMA3_DRV_Result edma3_test(
EDMA3_DRV_Handle hEdma,
unsigned int acnt,
unsigned int bcnt,
unsigned int ccnt,
EDMA3_DRV_SyncType syncType)
{
EDMA3_DRV_Result result = EDMA3_DRV_SOK;
EDMA3_DRV_PaRAMRegs paramSet = {0,0,0,0,0,0,0,0,0,0,0,0};
unsigned int chId = 0;
unsigned int tcc = 0;
int i;
unsigned int count;
unsigned int Istestpassed = 0u;
unsigned int numenabled = 0;
unsigned int BRCnt = 0;
int srcbidx = 0, desbidx = 0;
int srccidx = 0, descidx = 0;
acnt=65535;
bcnt=2;
//srcBuff1 = (signed char*) GLOBAL_ADDR(_srcBuff1);
//dstBuff1 = (signed char*) GLOBAL_ADDR(_dstBuff1);
srcBuff1 = (unsigned char*) 0xE1000000;//GLOBAL_ADDR(_srcBuff1);
dstBuff1 = (unsigned char*) 0xE2000000;//0x4001FC80;//GLOBAL_ADDR(_dstBuff1);
/* Initalize source and destination buffers */
for (count = 0u; count < (acnt*bcnt*ccnt); count++)
{
*((unsigned char*)0x00880000 + count) = (int)count;
/**
* No need to initialize the destination buffer as it is being invalidated.
dstBuff1[count] = initval;
*/
}
/*
* Note: These functions are required if the buffer is in DDR.
* For other cases, where buffer is NOT in DDR, user
* may or may not require the below functions.
*/
/* Flush the Source Buffer */
if (result == EDMA3_DRV_SOK)
{
result = Edma3_CacheFlush((unsigned int)srcBuff1, (acnt*bcnt*ccnt));
}
/* Invalidate the Destination Buffer */
if (result == EDMA3_DRV_SOK)
{
result = Edma3_CacheInvalidate((unsigned int)dstBuff1, (acnt*bcnt*ccnt));
}
/* EDMA3_ENABLE_DCACHE */
/* Set B count reload as B count. */
BRCnt = bcnt;
/* Setting up the SRC/DES Index */
srcbidx = (int)acnt;
desbidx = (int)acnt;
if (syncType == EDMA3_DRV_SYNC_A)
{
/* A Sync Transfer Mode */
srccidx = (int)acnt;
descidx = (int)acnt;
}
else
{
/* AB Sync Transfer Mode */
srccidx = ((int)acnt * (int)bcnt);
descidx = ((int)acnt * (int)bcnt);
}
/* Setup for Channel 1*/
tcc = EDMA3_DRV_TCC_ANY;
chId = EDMA3_DRV_DMA_CHANNEL_ANY;
/* Request any DMA channel and any TCC */
if (result == EDMA3_DRV_SOK)
{
result = EDMA3_DRV_requestChannel (hEdma, &chId, &tcc,
(EDMA3_RM_EventQueue)0,
&callback1, NULL);
}
if (result == EDMA3_DRV_SOK)
{
/* Fill the PaRAM Set with transfer specific information */
paramSet.srcAddr = (unsigned int)(srcBuff1);
paramSet.destAddr = (unsigned int)(dstBuff1);
/**
* Be Careful !!!
* Valid values for SRCBIDX/DSTBIDX are between �2768 and 32767
* Valid values for SRCCIDX/DSTCIDX are between �2768 and 32767
*/
paramSet.srcBIdx = srcbidx;
paramSet.destBIdx = desbidx;
paramSet.srcCIdx = srccidx;
paramSet.destCIdx = descidx;
/**
* Be Careful !!!
* Valid values for ACNT/BCNT/CCNT are between 0 and 65535.
* ACNT/BCNT/CCNT must be greater than or equal to 1.
* Maximum number of bytes in an array (ACNT) is 65535 bytes
* Maximum number of arrays in a frame (BCNT) is 65535
* Maximum number of frames in a block (CCNT) is 65535
*/
paramSet.aCnt = acnt;
paramSet.bCnt = bcnt;
paramSet.cCnt = ccnt;
/* For AB-synchronized transfers, BCNTRLD is not used. */
paramSet.bCntReload = BRCnt;
paramSet.linkAddr = 0xFFFFu;
/* Src & Dest are in INCR modes */
paramSet.opt &= 0xFFFFFFFCu;
/* Program the TCC */
paramSet.opt |= ((tcc << OPT_TCC_SHIFT) & OPT_TCC_MASK);
/* Enable Intermediate & Final transfer completion interrupt */
paramSet.opt |= (1 << OPT_ITCINTEN_SHIFT);
paramSet.opt |= (1 << OPT_TCINTEN_SHIFT);
if (syncType == EDMA3_DRV_SYNC_A)
{
paramSet.opt &= 0xFFFFFFFBu;
}
else
{
/* AB Sync Transfer Mode */
paramSet.opt |= (1 << OPT_SYNCDIM_SHIFT);
}
/* Now, write the PaRAM Set. */
result = EDMA3_DRV_setPaRAM(hEdma, chId, ¶mSet);
}
/*
* There is another way to program the PaRAM Set using specific APIs
* for different PaRAM set entries. It gives user more control and easier
* to use interface. User can use any of the methods.
* Below is the alternative way to program the PaRAM Set.
*/
/*
if (result == EDMA3_DRV_SOK)
{
result = EDMA3_DRV_setSrcParams (hEdma, chId, (unsigned int)(srcBuff1),
EDMA3_DRV_ADDR_MODE_INCR,
EDMA3_DRV_W8BIT);
}
if (result == EDMA3_DRV_SOK)
{
result = EDMA3_DRV_setDestParams (hEdma, chId, (unsigned int)(dstBuff1),
EDMA3_DRV_ADDR_MODE_INCR,
EDMA3_DRV_W8BIT);
}
if (result == EDMA3_DRV_SOK)
{
result = EDMA3_DRV_setSrcIndex (hEdma, chId, srcbidx, srccidx);
}
if (result == EDMA3_DRV_SOK)
{
result = EDMA3_DRV_setDestIndex (hEdma, chId, desbidx, descidx);
}
if (result == EDMA3_DRV_SOK)
{
if (syncType == EDMA3_DRV_SYNC_A)
{
result = EDMA3_DRV_setTransferParams (hEdma, chId, acnt, bcnt, ccnt,
BRCnt, EDMA3_DRV_SYNC_A);
}
else
{
result = EDMA3_DRV_setTransferParams (hEdma, chId, acnt, bcnt, ccnt,
BRCnt, EDMA3_DRV_SYNC_AB);
}
}
if (result == EDMA3_DRV_SOK)
{
result = EDMA3_DRV_setOptField (hEdma, chId,
EDMA3_DRV_OPT_FIELD_TCINTEN, 1u);
}
if (result == EDMA3_DRV_SOK)
{
result = EDMA3_DRV_setOptField (hEdma, chId,
EDMA3_DRV_OPT_FIELD_ITCINTEN, 1u);
}
*/
/*
* Since the transfer is going to happen in Manual mode of EDMA3
* operation, we have to 'Enable the Transfer' multiple times.
* Number of times depends upon the Mode (A/AB Sync)
* and the different counts.
*/
if (result == EDMA3_DRV_SOK)
{
/*Need to activate next param*/
if (syncType == EDMA3_DRV_SYNC_A)
{
numenabled = bcnt * ccnt;
}
else
{
/* AB Sync Transfer Mode */
numenabled = ccnt;
}
for (i = 0; i < numenabled; i++)
{
irqRaised1 = 0;
/*
* Now enable the transfer as many times as calculated above.
*/
result = EDMA3_DRV_enableTransfer (hEdma, chId,
EDMA3_DRV_TRIG_MODE_MANUAL);
if (result != EDMA3_DRV_SOK)
{
printf ("edma3_test: EDMA3_DRV_enableTransfer " \
"Failed, error code: %d\r\n", result);
break;
}
/* Wait for the Completion ISR. */
while (irqRaised1 == 0u)
{
/* Wait for the Completion ISR. */
printf ("waiting for interrupt…\n");
}
… ….
Allen35065:
注意看手册EDMA3 AB sync传输时,如果BCNT大于1,需要设置BIDX,BIDX范围是-32768-32767;因此一次传输可以访问32767*65536=2Gbyte,应该是足够用了。