TI中文支持网
TI专业的中文技术问题搜集分享网站

能否幫我看EDMA用Block Move從DDR搬到DDR那裡錯了?

您好, 我有到置頂下載範例 K1_STK_v1.1.zip

我用裡面的KeyStone_memory_EDMA_test() 改成我要的block move函式, 從DDR 0x88000000搬運到DDR 0x8D000000位置

我的板子是C6678, 能否幫我看那裡錯了, 我用下面我寫的void BlockMove_EDMA()函式,輸入來源位址,目的位址,圖的大小(單位byte),

搬一張2048X1024的圖,但都搬不過去,能否請教我那裡錯了,該怎麼修改, 抱歉我DSP還沒很熟,有依照Block Move範例做設定了,仍不會搬移.

void BlockMove_EDMA(unsigned int srcAddress, unsigned int dstAddress, unsigned int dataByteSize)
{
int i;
DDR_ECC_Config DDR_ECC_cfg; //ECC: error correction code

//clear cache; protect L1 as cache
KeyStone_common_CPU_init();

//print device information.
KeyStone_common_device_init();

//enable exception handling
KeyStone_Exception_cfg(TRUE);

//reset cache from previous run. Not required from cold reset or power up.
CACHE_setL1PSize(CACHE_L1_0KCACHE);
CACHE_setL1DSize(CACHE_L1_0KCACHE);
CACHE_setL2Size(CACHE_0KCACHE);
//disable cache and prefetch
for(i= 16; i< 256; i++)
gpCGEM_regs->MAR[i]=0;

//XMC memory address extension/mapping and memory protection.
// *remap Shared L2 to 0x18000000 for noncacheable and nonprefetchable access, 0x18000000 is reserved
KeyStone_XMC_MPAX_setup(XMC_MPAX_cfg_table, 0,
sizeof(XMC_MPAX_cfg_table)/sizeof(MPAX_Config));

EDMA_init();

//allocate EDMA TCs between cores sequentially
allocate_EDMA_TC(DNUM, 1); 

memset((void *)&DDR_ECC_cfg, 0, sizeof(DDR_ECC_cfg));

if(C6678_EVM==gDSP_board_type)
{
KeyStone_main_PLL_init(100, 10, 1);
}
else
{
puts("Unknown DSP board type!");
return;
}

//DDR init 66.66667*20/1= 1333, set DDR clock rate
KeyStone_DDR_init (66.66667, 20, 1, &DDR_ECC_cfg);

//make remapped SL2(shared L2) noncacheable, nonprefetchable
gpCGEM_regs->MAR[(REMAPPED_SL2_TEST_START_ARRD/16/1024/1024)]=0; //Reg 24

//make DDR cacheable and prefetchable
for(i= 0; i< (uiDDREndAddress-DDR_TEST_START_ARRD)/16/1024/1024; i++)
gpCGEM_regs->MAR[(DDR_TEST_START_ARRD/16/1024/1024)+i]=1|
(1<<CSL_CGEM_MAR0_PFX_SHIFT);

//the value of NUM_MM field, 0 means 1, 1 means 2…
number_of_cores= ((gpCGEM_regs->L2CFG&CSL_CGEM_L2CFG_NUM_MM_MASK)>>
CSL_CGEM_L2CFG_NUM_MM_SHIFT)+1;

//make other cores L2 cacheable and prefetchable
for(i=0; i< number_of_cores; i++)
{
gpCGEM_regs->MAR[0x10800000/16/1024/1024+i]=1|
(1<<CSL_CGEM_MAR0_PFX_SHIFT);
}

{
CACHE_setL1PSize(CACHE_L1_0KCACHE);
CACHE_setL1DSize(CACHE_L1_0KCACHE);
CACHE_setL2Size(CACHE_0KCACHE);
printf("Set 0KB L1P, 0KB L1D, 0KB L2\n");

int j;
unsigned int uiAddress, uiSrcAddress, uiDstAddress, uiFailCount=0, uiTotalFailCount=0;
EDMA_CC_Channel_Num CC_channel;
unsigned int uiDmaBufAddress;
unsigned int uiEndAddress, uiDMA_count;

uiSrcAddress = GLOBAL_ADDR(srcAddress);
uiAddress = GLOBAL_ADDR(dstAddress);

CC_channel = get_EDMA_TC();

uiEndAddress= uiAddress + dataByteSize;

while(uiAddress < uiEndAddress)
{
uiDMA_count = uiEndAddress – uiAddress;
if(uiDMA_count > dataByteSize)
uiDMA_count = dataByteSize; //uiDmaBufByteSize = 32*1024

DMA_Wait wait = DMA_WAIT;
CSL_TpccRegs* EDMACCRegs;
unsigned int uiChannel;
volatile Uint32 * TPCC_ESR;
volatile Uint32 * TPCC_IPR;
volatile Uint32 * TPCC_ICR;
EDMACCRegs= gpEDMA_CC_regs[CC_channel>>16];
uiChannel = CC_channel&0xFF; //uiChannel = 0

EDMACCRegs->PARAMSET[uiChannel].OPT=
CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, 
CSL_EDMA3_TCCH_DIS, 
CSL_EDMA3_ITCINT_DIS, 
CSL_EDMA3_TCINT_EN, 
uiChannel,
CSL_EDMA3_TCC_NORMAL, 
CSL_EDMA3_FIFOWIDTH_NONE, 
CSL_EDMA3_STATIC_DIS, 
CSL_EDMA3_SYNC_A, 
CSL_EDMA3_ADDRMODE_INCR,
CSL_EDMA3_ADDRMODE_INCR); 
EDMACCRegs->PARAMSET[uiChannel].SRC= GLOBAL_ADDR(srcAddress);
EDMACCRegs->PARAMSET[uiChannel].A_B_CNT=CSL_EDMA3_CNT_MAKE(uiDMA_count&0xFFFF, 1); 
EDMACCRegs->PARAMSET[uiChannel].DST= GLOBAL_ADDR(dstAddress);
EDMACCRegs->PARAMSET[uiChannel].SRC_DST_BIDX= 0;
EDMACCRegs->PARAMSET[uiChannel].LINK_BCNTRLD= CSL_EDMA3_LINKBCNTRLD_MAKE(0xFFFF, 1); 
EDMACCRegs->PARAMSET[uiChannel].SRC_DST_CIDX= 0;
EDMACCRegs->PARAMSET[uiChannel].CCNT= 1;

if(uiChannel<32)
{
TPCC_ESR= &EDMACCRegs->TPCC_ESR;
TPCC_IPR= &EDMACCRegs->TPCC_IPR;
TPCC_ICR= &EDMACCRegs->TPCC_ICR;
}
else
{
TPCC_ESR= &EDMACCRegs->TPCC_ESRH;
TPCC_IPR= &EDMACCRegs->TPCC_IPRH;
TPCC_ICR= &EDMACCRegs->TPCC_ICRH;
uiChannel -= 32;
}

/*Manually trigger the EDMA on the event set register*/
(*TPCC_ESR)= 1<<(uiChannel);

if(wait)
{
/*wait for completion*/
while(0==((*TPCC_IPR)&(1<<(uiChannel))));

/*clear completion flag*/
(*TPCC_ICR)= 1<<(uiChannel);
}

uiAddress += uiDMA_count;
}
}
}

在主程式裡執行

unsigned int length = 2048*1024;

BlockMove_EDMA(0x88000000, 0x8D000000, length);

Chia-Hung Chen1:

EDMACCRegs->PARAMSET[uiChannel].A_B_CNT=CSL_EDMA3_CNT_MAKE(uiDMA_count&0xFFFF, 1); 

上面這行改成

EDMACCRegs->PARAMSET[uiChannel].A_B_CNT=CSL_EDMA3_CNT_MAKE(uiDMA_count&0xFFFFFFFF, 1); 

因為2048*1024的圖大小為0x00200000

Chia-Hung Chen1:

回复 Chia-Hung Chen1:

我剛搬運130X355 = 46150大小的圖是可以搬運的, 但第1個像素的數質是錯的,

2048X1024圖的大小 因為超過ACNT的最大值65535, 所以好像無法搬運,

可能ACNT和BCNT都要設對才行

Allen35065:

回复 Chia-Hung Chen1:

建议你还是先看看EDMA手册的AB-Sync方式以及Parameter参数章节;

如果地址是连续的,可以把ACNT设成2048,BCNT设为1024,BINX设成2048就可以传输2048×1024的图像。

赞(0)
未经允许不得转载:TI中文支持网 » 能否幫我看EDMA用Block Move從DDR搬到DDR那裡錯了?
分享到: 更多 (0)