Hi! im using TMS320DM6437 evm board. i want to use edma for memory transfer but i couldnt make transfer fast. for example for 1000 iteration and for 800 byte data transfer DSPLIB's DSP_blk_move function and edma transfer time are like this :
edma time = 0.078325 , dsp_blk_move time = 0.002972
i think i have a problem about edma's usage. but i implemented my edma code like edma3 driver example.
my edma code is below can anyone say what is my mistake?
Thanks.
#include "common.h"
unsigned int _srcBuff1[MAX_BUFFER_SIZE];
unsigned int _dstBuff1[MAX_BUFFER_SIZE];
unsigned int *srcBuff1;
unsigned int *dstBuff1;
/**
* \brief EDMA3 mem-to-mem data copy test case, using a DMA channel.
*
*
* \param acnt [IN] Number of bytes in an array
* \param bcnt [IN] Number of arrays in a frame
* \param ccnt [IN] Number of frames in a block
* \param syncType [IN] Synchronization type (A/AB Sync)
*
* \return EDMA3_DRV_SOK or EDMA3_DRV Error Code
*/
extern EDMA3_DRV_Result edma3(
EDMA3_DRV_Handle hEdma, unsigned int *_srcBuf, unsigned int *_dstBuf,unsigned int srcAdress, unsigned int dstAdress,
unsigned int acnt,
unsigned int bcnt,
unsigned int ccnt,
EDMA3_DRV_SyncType syncType,unsigned int srcIndex,unsigned int dstIndex)
{
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;
srcBuff1 = (unsigned int*)_srcBuf;
dstBuff1 = (unsigned int*)_dstBuf;
/* Initalize source and destination buffers */
#ifdef EDMA3_ENABLE_DCACHE
/*
* 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, (srcIndex * acnt*bcnt*ccnt));
}
/* Invalidate the Destination Buffer */
if (result == EDMA3_DRV_SOK)
{
result = Edma3_CacheInvalidate((unsigned int)dstBuff1, (dstIndex * acnt*bcnt*ccnt));
}
#endif /* EDMA3_ENABLE_DCACHE */
/* Set B count reload as B count. */
BRCnt = bcnt;
/* Setting up the SRC/DES Index */
srcbidx = (int)acnt * srcIndex;
desbidx = (int)acnt * dstIndex;
if (syncType == EDMA3_DRV_SYNC_A)
{
/* A Sync Transfer Mode */
srccidx = (int)acnt * srcIndex;
descidx = (int)acnt * dstIndex;
}
else
{
/* AB Sync Transfer Mode */
srccidx = ((int)acnt * (int)bcnt * srcIndex);
descidx = ((int)acnt * (int)bcnt * dstIndex);
}
/* 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);
}
/*
* 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 + srcAdress),
EDMA3_DRV_ADDR_MODE_INCR,
EDMA3_DRV_W16BIT);
}
if (result == EDMA3_DRV_SOK)
{
result = EDMA3_DRV_setDestParams (hEdma, chId, (unsigned int)(dstBuff1 + dstAdress),
EDMA3_DRV_ADDR_MODE_INCR,
EDMA3_DRV_W16BIT);
}
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 on Master Channel.
* You can insert your code here to do something
* meaningful.
*/
}
/* Check the status of the completed transfer */
if (irqRaised1 < 0)
{
/* Some error occured, break from the FOR loop. */
printf ("\r\nedma3_test: Event Miss Occured!!!\r\n");
/* Clear the error bits first */
result = EDMA3_DRV_clearErrorBits (hEdma, chId);
break;
}
}
}
/* Free the previously allocated channel. */
result = EDMA3_DRV_freeChannel (hEdma, chId);
if (result != EDMA3_DRV_SOK)
{
printf("edma3_test: EDMA3_DRV_freeChannel() FAILED, " \
"error code: %d\r\n", result);
}
return result;
}