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.

TMS320C6678: C6678CSL库EDMA3的AB同步传输无法启用除0通道以外的别的通道

Part Number: TMS320C6678

在C6678的CSL库上更改EDMA3函数,发现AB同步模式时,只能选择通道0,选其他通道会导致传输失败,并且报错:

TMS320C66x_0: Warning: DMA channel 0 did not have DCHMAP programmed even though channel mapping exists on device. Using default PARAM of 0 

但使用A同步时可以开启别的通道。我的函数如下:


void CSL_Edma3_transfer(void* src, void* dst,
Uint16 ACNT, Uint16 CCNT, Uint16 BCNT,
Uint8 mode, Uint8 chN )
{

if(chN > 15){
printf ("channel > 15");
return;
}

if(ACNT==0||BCNT==0||CCNT==0){
printf ("ACNT==0 or BCNT==0 or CCNT==0");
return;
}

CSL_Edma3Context context;
CSL_Edma3Handle hModule;
CSL_Edma3Obj edmaObj;
CSL_Status status;
CSL_Edma3CmdDrae regionAccess;
CSL_Edma3CmdIntr regionIntr;
CSL_Edma3ChannelObj chObj;
CSL_Edma3ChannelAttr chAttr;
CSL_Edma3ChannelHandle hChannel;
CSL_Edma3ParamHandle hParamPing;
CSL_Edma3ParamSetup myParamSetup;


Uint8 instNum = edma3Cfg[DNUM].instNum;
Uint8* channelNum = edma3Cfg[DNUM].channelNum;
Int32 regionNum = edma3Cfg[DNUM].regionNum;
Uint16 srcBidx;
Uint16 dstBidx;
Uint16 srcCidx;
Uint16 dstCidx;

switch(mode){
case modeVector: //A同步
srcBidx = 0;
dstBidx = 0;
srcCidx = 0;
dstCidx = 0;
break;
case modeArray: //AB同步
srcBidx = ACNT;
dstBidx = ACNT;
srcCidx = ACNT*BCNT;
dstCidx = ACNT*BCNT;
break;
case modeTransp: //AB同步
srcBidx = ACNT;
dstBidx = CCNT*ACNT;
srcCidx = ACNT*BCNT;
dstCidx = ACNT;
break;
case modeSubrow: //AB同步
srcBidx = ACNT;
dstBidx = ACNT;
srcCidx = ACNT*BCNT*2;
dstCidx = ACNT*BCNT;
break;
default:
break;
}

/* Module initialization. This function is idem-potent. */
if (CSL_edma3Init(&context) != CSL_SOK)
{
printf ("Error: EDMA module initialization failed\n");
return;
}

/* Module level open. EDMA Instance 1 and 2: Supports 64 DMA Channels. */
hModule = CSL_edma3Open(&edmaObj, instNum, NULL, &status);
if ((hModule == NULL) || (status != CSL_SOK))
{
printf ("Error: EDMA module open failed\n");
return;
}

/*
* 配置影子区域,用于多核并行调用本函数
* DRAE enable(16 Bits) for the shadow region; since there are 16 channels for each core.
*/
regionAccess.region = regionNum;
regionIntr.region = regionNum;
switch(regionNum){
case CSL_EDMA3_REGION_0:
regionAccess.drae = 0x0000FFFF;
regionAccess.draeh = 0x00000000;
regionIntr.intr = 0x0000FFFF;
regionIntr.intrh = 0x00000000;
break;
case CSL_EDMA3_REGION_1:
regionAccess.drae = 0xFFFF0000;
regionAccess.draeh = 0x00000000;
regionIntr.intr = 0xFFFF0000;
regionIntr.intrh = 0x00000000;
break;
case CSL_EDMA3_REGION_2:
regionAccess.drae = 0x00000000;
regionAccess.draeh = 0x0000FFFF;
regionIntr.intr = 0x00000000;
regionIntr.intrh = 0x0000FFFF;
break;
case CSL_EDMA3_REGION_3:
regionAccess.drae = 0x00000000;
regionAccess.draeh = 0xFFFF0000;
regionIntr.intr = 0x00000000;
regionIntr.intrh = 0xFFFF0000;
break;
case CSL_EDMA3_REGION_4:
regionAccess.drae = 0x0000FFFF;
regionAccess.draeh = 0x00000000;
regionIntr.intr = 0x0000FFFF;
regionIntr.intrh = 0x00000000;
break;
case CSL_EDMA3_REGION_5:
regionAccess.drae = 0xFFFF0000;
regionAccess.draeh = 0x00000000;
regionIntr.intr = 0xFFFF0000;
regionIntr.intrh = 0x00000000;
break;
case CSL_EDMA3_REGION_6:
regionAccess.drae = 0x00000000;
regionAccess.draeh = 0x0000FFFF;
regionIntr.intr = 0x00000000;
regionIntr.intrh = 0x0000FFFF;
break;
case CSL_EDMA3_REGION_7:
regionAccess.drae = 0x00000000;
regionAccess.draeh = 0xFFFF0000;
regionIntr.intr = 0x00000000;
regionIntr.intrh = 0xFFFF0000;
break;
}
if (CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_DMAREGION_ENABLE,&regionAccess) != CSL_SOK)
{
printf ("Error: EDMA region enable command failed\n");
return;
}

/* Interrupt enable */
if (CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTR_ENABLE, &regionIntr) != CSL_SOK)
{
printf ("Error: EDMA interrupts enable command failed\n");
return;
}

/* Open the channel in context of the specified region number. */
chAttr.regionNum = regionNum;
chAttr.chaNum = channelNum[chN];
hChannel = CSL_edma3ChannelOpen(&chObj, instNum, &chAttr, &status);
if ((hChannel == NULL) || (status != CSL_SOK))
{
printf ("Error: EDMA channel open failed\n");
return;
}

/* For first EDMA instance there are only 2 TCs and 2 event queues
* Modify the channel default queue setup from 0 to 1
* For EDMA instance 1 and 2 maximum of 4 TCs and 4 event queues are supported
* Change Channel Default queue setup from 0 to 3
*/
if(instNum == 1){
if (CSL_edma3HwChannelSetupQue(hChannel,CSL_EDMA3_QUE_0) != CSL_SOK)
{
printf ("Error: EDMA channel setup queue failed\n");
return;
}
}
else{
if (CSL_edma3HwChannelSetupQue(hChannel,CSL_EDMA3_QUE_1) != CSL_SOK)
{
printf ("Error: EDMA channel setup queue failed\n");
return;
}
}

// /* Map the DMA Channel to PARAM Block 2. */
// CSL_edma3MapDMAChannelToParamBlock(hModule, channelNum[chN], channelNum[chN]);

/* Map the DMA Channel to the appropriate PARAM. */
if (CSL_edma3HwChannelSetupParam(hChannel, channelNum[chN]) != CSL_SOK)
{
printf ("Error: EDMA channel setup param failed\n");
return;
}

/* Obtain a handle to parameter set */
hParamPing = CSL_edma3GetParamHandle(hChannel, channelNum[chN], &status);
if (hParamPing == NULL) {
printf ("Error: EDMA get param handle for param entry failed\n");
return;
}

/* Setup the param set
/* 重要修改1:启用传输完成链接 */
Uint8 itcchMode = (BCNT > 1 || CCNT > 1) ?
CSL_EDMA3_ITCCH_EN : // 多维传输启用内部链接
CSL_EDMA3_ITCCH_DIS; // 一维传输可以禁用内部链接
/* 重要修改2:修改参数更新模式 */
Uint32 staticMode = (BCNT > 1 || CCNT > 1) ?
CSL_EDMA3_STATIC_DIS : //非静态 参数集更新 内部链接必须启用
CSL_EDMA3_STATIC_EN;
/* 重要修改3:修改同步模式 */
Uint32 syncMode = (BCNT > 1 || CCNT > 1) ?
CSL_EDMA3_SYNC_AB : // 多维传输启用AB同步
CSL_EDMA3_SYNC_A;

myParamSetup.option = CSL_EDMA3_OPT_MAKE( itcchMode, \
CSL_EDMA3_TCCH_DIS, \
CSL_EDMA3_ITCINT_DIS, \
CSL_EDMA3_TCINT_EN,\
0, \
CSL_EDMA3_TCC_NORMAL,\
CSL_EDMA3_FIFOWIDTH_NONE, \
staticMode, \
syncMode, \
CSL_EDMA3_ADDRMODE_INCR, \
CSL_EDMA3_ADDRMODE_INCR
);
myParamSetup.srcAddr = (Uint32)src; //源地址
myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(ACNT,BCNT); //A_B_计数
myParamSetup.dstAddr = (Uint32)dst; //目的地址
myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(srcBidx,dstBidx); //源_目的_B索引
myParamSetup.linkBcntrld= CSL_EDMA3_LINKBCNTRLD_MAKE(CSL_EDMA3_LINK_NULL, 0); //链接重载
myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(srcCidx,dstCidx); //源_目的_C索引
myParamSetup.cCnt = CCNT;

/* Setup the Ping Entry */
if (CSL_edma3ParamSetup(hParamPing,&myParamSetup) != CSL_SOK)
{
printf("Error: EDMA ping parameter entry setup is failed\n");
return;
}

/* Enable channel */
if (CSL_edma3HwChannelControl(hChannel,CSL_EDMA3_CMD_CHANNEL_ENABLE, NULL) != CSL_SOK)
{
printf("Error: EDMA channel enable command is failed\n");
return;
}

regionIntr.region = regionNum;
regionIntr.intr = 0; //清除IPR/IPRH
regionIntr.intrh = 0;

/* Manually trigger the channel */
if (CSL_edma3HwChannelControl(hChannel,CSL_EDMA3_CMD_CHANNEL_SET,NULL) != CSL_SOK)
{
printf("Error: EDMA channel set command is failed\n");
return;
}

do {
/* Poll on interrupt bit */
CSL_edma3GetHwStatus(hModule,CSL_EDMA3_QUERY_INTRPEND,&regionIntr);
} while (!(regionIntr.intr & 0x1)); //检测TCC对应的位是否有中断挂起

/* Clear interrupt bit 0 */
if (CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTRPEND_CLEAR, &regionIntr) != CSL_SOK)
{
printf("Error: EDMA clear interrupt bit 0 command is failed\n");
return;
}

/* Close channel */
if (CSL_edma3ChannelClose(hChannel) != CSL_SOK)
{
printf("Error: EDMA channel close failed\n");
return;
}

/* Close EDMA module */
if (CSL_edma3Close(hModule) != CSL_SOK)
{
printf("Error: EDMA module close failed\n");
return;
}

}