在TI的K1_STK_v1.1例程上,测试EDMA,测试OK,将EDMA修改为QDMA,数据不能够搬移。EDMA的函数如下:
void my_EDMA_A_copy(
unsigned int edma3cc_id,// 0 1 2
unsigned int channel,
unsigned int opt,
unsigned int srcAddr, unsigned int dstAddr, unsigned int byteCount, DMA_Wait wait
)
{
CSL_TpccRegs* EDMACCRegs;
//unsigned int channel;
volatile Uint32 * TPCC_ESR;
volatile Uint32 * TPCC_IPR;
volatile Uint32 * TPCC_ICR;
EDMACCRegs= gpEDMA_CC_regs[edma3cc_id];//确定采用哪个通道控制器0 1 2
opt&=~(0x3f<<12);
opt|=(channel<<12);
EDMACCRegs->PARAMSET[channel].OPT=opt;
EDMACCRegs->PARAMSET[channel].SRC= srcAddr;
EDMACCRegs->PARAMSET[channel].A_B_CNT=CSL_EDMA3_CNT_MAKE(byteCount&0xFFFF, 1);
EDMACCRegs->PARAMSET[channel].DST= dstAddr;
EDMACCRegs->PARAMSET[channel].SRC_DST_BIDX= 0;
EDMACCRegs->PARAMSET[channel].LINK_BCNTRLD= CSL_EDMA3_LINKBCNTRLD_MAKE(0xFFFF, 1);
EDMACCRegs->PARAMSET[channel].SRC_DST_CIDX= 0;
EDMACCRegs->PARAMSET[channel].CCNT= 1;
if(channel<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;
channel -= 32;
}
/*Manually trigger the EDMA*/
(*TPCC_ESR)= 1<<(channel);
if(wait)
{
/*wait for completion*/
while(0==((*TPCC_IPR)&(1<<(channel))));
/*clear completion flag*/
(*TPCC_ICR)= 1<<(channel);
}
}
QDMA的函数如下:
void my_QDMA_A_copy(
unsigned int edma3cc_id,// 0 1 2
unsigned int channel,//0-7
unsigned int opt,
unsigned int srcAddr,
unsigned int dstAddr,
unsigned int byteCount,
DMA_Wait wait
)
{
CSL_TpccRegs* EDMACCRegs;
unsigned int param_channel;
//volatile Uint32 * TPCC_ESR;
volatile Uint32 * TPCC_IPR;
volatile Uint32 * TPCC_ICR;
EDMACCRegs= gpEDMA_CC_regs[edma3cc_id];//确定采用哪个通道控制器0 1 2
param_channel=EDMACCRegs->TPCC_QCHMAP[channel];//确定param空间
opt&=~(0x3f<<12);
opt|=(channel<<12);
EDMACCRegs->PARAMSET[param_channel].OPT=opt;
EDMACCRegs->PARAMSET[param_channel].SRC= srcAddr;
EDMACCRegs->PARAMSET[param_channel].A_B_CNT=CSL_EDMA3_CNT_MAKE(byteCount&0xFFFF, 1);
EDMACCRegs->PARAMSET[param_channel].DST= dstAddr;
EDMACCRegs->PARAMSET[param_channel].SRC_DST_BIDX= 0;
EDMACCRegs->PARAMSET[param_channel].LINK_BCNTRLD= CSL_EDMA3_LINKBCNTRLD_MAKE(0xFFFF, 1);
EDMACCRegs->PARAMSET[param_channel].SRC_DST_CIDX= 0;
EDMACCRegs->PARAMSET[param_channel].CCNT= 1;
//TPCC_ESR= &EDMACCRegs->TPCC_ESR;
TPCC_IPR= &EDMACCRegs->TPCC_IPR;
TPCC_ICR= &EDMACCRegs->TPCC_ICR;
/*Manually trigger the EDMA*/
//(*TPCC_ESR)= 1<<(channel);
if(wait)
{
/*wait for completion*/
while(0==((*TPCC_IPR)&(1<<(channel))));
/*clear completion flag*/
(*TPCC_ICR)= 1<<(channel);
}
}
EDMA的初始化如下:
void EDMA_init ()
{
int i;
unsigned int * uipPaRAM;
/*clear PaRAM*/
uipPaRAM= (unsigned int *)&(gpEDMA_CC0_regs->PARAMSET[0]);
for(i=0; i<8*CSL_EDMA3_TPCC0_NUM_PARAMSETS; i++) *uipPaRAM++=0;
uipPaRAM= (unsigned int *)&(gpEDMA_CC1_regs->PARAMSET[0]);
for(i=0; i<8*CSL_EDMA3_TPCC1_NUM_PARAMSETS; i++) *uipPaRAM++=0;
uipPaRAM= (unsigned int *)&(gpEDMA_CC2_regs->PARAMSET[0]);
for(i=0; i<8*CSL_EDMA3_TPCC2_NUM_PARAMSETS; i++) *uipPaRAM++=0;
/*Assign PaRAM for different edma channels*/
for(i=0; i<CSL_EDMA3_TPCC0_NUM_DMACH; i++) gpEDMA_CC0_regs->TPCC_DCHMAP[i] = i<< CSL_TPCC_TPCC_DCHMAP0_PAENTRY_SHIFT;
for(i=0; i<CSL_EDMA3_TPCC1_NUM_DMACH; i++) gpEDMA_CC1_regs->TPCC_DCHMAP[i] = i<< CSL_TPCC_TPCC_DCHMAP0_PAENTRY_SHIFT;
for(i=0; i<CSL_EDMA3_TPCC2_NUM_DMACH; i++) gpEDMA_CC2_regs->TPCC_DCHMAP[i] = i<< CSL_TPCC_TPCC_DCHMAP0_PAENTRY_SHIFT;
/*Assign PaRAM for different qdma channels*/
/*Assign TC/Queue for different channels*/
gpEDMA_CC0_regs->TPCC_DMAQNUM[0]= 0x10101010;
gpEDMA_CC0_regs->TPCC_DMAQNUM[1]= 0x10101010;
gpEDMA_CC1_regs->TPCC_DMAQNUM[0]= 0x32103210;
gpEDMA_CC1_regs->TPCC_DMAQNUM[1]= 0x32103210;
gpEDMA_CC1_regs->TPCC_DMAQNUM[2]= 0x32103210;
gpEDMA_CC1_regs->TPCC_DMAQNUM[3]= 0x32103210;
gpEDMA_CC1_regs->TPCC_DMAQNUM[4]= 0x32103210;
gpEDMA_CC1_regs->TPCC_DMAQNUM[5]= 0x32103210;
gpEDMA_CC1_regs->TPCC_DMAQNUM[6]= 0x32103210;
gpEDMA_CC1_regs->TPCC_DMAQNUM[7]= 0x32103210;
gpEDMA_CC2_regs->TPCC_DMAQNUM[0]= 0x32103210;
gpEDMA_CC2_regs->TPCC_DMAQNUM[1]= 0x32103210;
gpEDMA_CC2_regs->TPCC_DMAQNUM[2]= 0x32103210;
gpEDMA_CC2_regs->TPCC_DMAQNUM[3]= 0x32103210;
gpEDMA_CC2_regs->TPCC_DMAQNUM[4]= 0x32103210;
gpEDMA_CC2_regs->TPCC_DMAQNUM[5]= 0x32103210;
gpEDMA_CC2_regs->TPCC_DMAQNUM[6]= 0x32103210;
gpEDMA_CC2_regs->TPCC_DMAQNUM[7]= 0x32103210;
/*clear any events and status*/
gpEDMA_CC0_regs->TPCC_ECR= 0xFFFF;
gpEDMA_CC0_regs->TPCC_EECR= 0xFFFF;
gpEDMA_CC0_regs->TPCC_ICR= 0xFFFF;
gpEDMA_CC0_regs->TPCC_IECR= 0xFFFF;
gpEDMA_CC0_regs->TPCC_EMCR= 0xFFFF;
gpEDMA_CC0_regs->TPCC_QEMCR= 0xFFFF;
gpEDMA_CC0_regs->TPCC_CCERRCLR= 0xFFFF;
gpEDMA_CC0_regs->TPCC_SECR= 0xFFFF;
gpEDMA_CC1_regs->TPCC_ECR= 0xFFFFFFFF;
gpEDMA_CC1_regs->TPCC_ECRH= 0xFFFFFFFF;
gpEDMA_CC1_regs->TPCC_EECR= 0xFFFFFFFF;
gpEDMA_CC1_regs->TPCC_EECRH= 0xFFFFFFFF;
gpEDMA_CC1_regs->TPCC_ICR= 0xFFFFFFFF;
gpEDMA_CC1_regs->TPCC_ICRH= 0xFFFFFFFF;
gpEDMA_CC1_regs->TPCC_IECR= 0xFFFFFFFF;
gpEDMA_CC1_regs->TPCC_IECRH= 0xFFFFFFFF;
gpEDMA_CC1_regs->TPCC_EMCR= 0xFFFFFFFF;
gpEDMA_CC1_regs->TPCC_EMCRH= 0xFFFFFFFF;
gpEDMA_CC1_regs->TPCC_QEMCR= 0xFFFFFFFF;
gpEDMA_CC1_regs->TPCC_CCERRCLR= 0xFFFF;
gpEDMA_CC1_regs->TPCC_SECR= 0xFFFFFFFF;
gpEDMA_CC1_regs->TPCC_SECRH= 0xFFFFFFFF;
gpEDMA_CC2_regs->TPCC_ECR= 0xFFFFFFFF;
gpEDMA_CC2_regs->TPCC_ECRH= 0xFFFFFFFF;
gpEDMA_CC2_regs->TPCC_EECR= 0xFFFFFFFF;
gpEDMA_CC2_regs->TPCC_EECRH= 0xFFFFFFFF;
gpEDMA_CC2_regs->TPCC_ICR= 0xFFFFFFFF;
gpEDMA_CC2_regs->TPCC_ICRH= 0xFFFFFFFF;
gpEDMA_CC2_regs->TPCC_IECR= 0xFFFFFFFF;
gpEDMA_CC2_regs->TPCC_IECRH= 0xFFFFFFFF;
gpEDMA_CC2_regs->TPCC_EMCR= 0xFFFFFFFF;
gpEDMA_CC2_regs->TPCC_EMCRH= 0xFFFFFFFF;
gpEDMA_CC2_regs->TPCC_QEMCR= 0xFFFFFFFF;
gpEDMA_CC2_regs->TPCC_CCERRCLR= 0xFFFF;
gpEDMA_CC2_regs->TPCC_SECR= 0xFFFFFFFF;
gpEDMA_CC2_regs->TPCC_SECRH= 0xFFFFFFFF;
for(i=0; i<NUM_EDMA_TC; i++)
{
//Clear TC error
gpEDMA_TC_regs[i]->TPTC_ERRCLR= 0xF;
//enable error interrupt
gpEDMA_TC_regs[i]->TPTC_ERREN= (1<<CSL_TPTC_TPTC_ERREN_MMRAERR_SHIFT)
|(1<<CSL_TPTC_TPTC_ERREN_TRERR_SHIFT)
|(1<<CSL_TPTC_TPTC_ERREN_BUSERR_SHIFT);
}
}
qdma的初始化如下:
void my_qdma_init(unsigned int TRWORD)
{
int i;
i=XHL_CSL_EDMA3_QCHMAP_MAKE(
0x1ff,//PAENTRY
0x7
);
//设置CC0的8个QDMA通道的param空间及触发寄存器
for(i=0; i<CSL_EDMA3_TPCC0_NUM_QDMACH; i++)
{
gpEDMA_CC0_regs->TPCC_QCHMAP[i] = XHL_CSL_EDMA3_QCHMAP_MAKE(
CSL_EDMA3_TPCC0_NUM_PARAMSETS-8-1+i,//PAENTRY
TRWORD
);
}
//设置CC1的8个QDMA通道的param空间及触发寄存器
for(i=0; i<CSL_EDMA3_TPCC1_NUM_QDMACH; i++)
{
gpEDMA_CC1_regs->TPCC_QCHMAP[i] = XHL_CSL_EDMA3_QCHMAP_MAKE(
CSL_EDMA3_TPCC1_NUM_PARAMSETS-8-1+i,//PAENTRY
TRWORD
);
}
//设置CC2的8个QDMA通道的param空间及触发寄存器
for(i=0; i<CSL_EDMA3_TPCC2_NUM_QDMACH; i++)
{
gpEDMA_CC2_regs->TPCC_QCHMAP[i] = XHL_CSL_EDMA3_QCHMAP_MAKE(
CSL_EDMA3_TPCC2_NUM_PARAMSETS-8-1+i,//PAENTRY
TRWORD
);
}
gpEDMA_CC0_regs->TPCC_QDMAQNUM= 0x32103210;
gpEDMA_CC1_regs->TPCC_QDMAQNUM= 0x32103210;
gpEDMA_CC2_regs->TPCC_QDMAQNUM= 0x32103210;
}
user1212849:
我的设置思路是:在EDMA_init中主要实现EDMA中的三个通道控制器的EDMA通道与param空间关联。my_qdma_init主要实现EDMA中的三个通道控制器的QDMA通道与param空间关联.
Shine:
回复 user1212849:
QDMA数据搬移问题一般跟配置有关,建议在配置完启动前,先查看QDMA相关的配置是否正确,然后启动QDMA,再查看cnt等配置是否有更新。可以参考processor SDK里的例程pdk_c667x_2_0_5\packages\ti\csl\example\edma。