I have create 3 functions based on the edma_test: QdmaInit, QdmaXfer, and QdmaDone (see below). The following test works:
for (core=0; core!=1; core++) {
if (SUCCESS == QdmaInit(core, srcBuff1, dstBuff1))
if (SUCCESS == QdmaXfer(core, true))
if (!Verify_Transfer( 256, 1, 1, 0, 0, 0, 0, srcBuff1, dstBuff1,TRUE))
return ERROR;
}
but if I don't wait for the previous transfer to complete (i.e. poll the IPR bit), the next transfer (core=1) never completes:
for (core=0; core!=1; core++) {
if (QdmaInit(core, srcBuff1, dstBuff1))
if (!QdmaXfer(core, false))
return ERROR;
}
for (core=0; core!=1; core++) {
if (QdmaDone(core))
if (!Verify_Transfer( 256, 1, 1, 0, 0, 0, 0, srcBuff1, dstBuff1,TRUE))
return ERROR;
}
Here are the QDMA functions I've created:
Int32 QdmaInit(Uint8 coreId, Uint32 *src, Uint32 *dst)
{
CSL_Edma3Context context;
CSL_Edma3Obj edmaObj;
CSL_Edma3Handle hModule;
CSL_Edma3CmdQrae qraeSetup;
CSL_Edma3CmdDrae regionAccess;
CSL_Edma3ChannelAttr chAttr;
CSL_Edma3ChannelObj chObj;
CSL_Edma3ChannelHandle hChannel;
CSL_Edma3ParamHandle hParam;
CSL_Edma3ParamSetup paramSetup;
CSL_Status status;
/* Module initialization */
if (CSL_edma3Init(&context) != CSL_SOK)
{
LogDebug ("Error: EDMA module initialization failed\n");
return ERROR;
}
/* Module level open */
hModule = CSL_edma3Open(&edmaObj, 0, NULL, &status);
if ((hModule == NULL) || (status != CSL_SOK))
{
LogDebug ("Error: EDMA module open failed\n");
return ERROR;
}
/* Shadow Region: Enable DMA region access (bits 0-15) */
regionAccess.region = coreId;
regionAccess.drae = 0xFFFF;
regionAccess.draeh = 0x0000;
if (CSL_edma3HwControl(hModule, CSL_EDMA3_CMD_DMAREGION_ENABLE, ®ionAccess\
) != CSL_SOK)
{
LogDebug ("Error: EDMA region enable command failed\n");
return ERROR;
}
/* Enable access for all QDMA channels in the SHADOW Region. */
qraeSetup.region = coreId;
qraeSetup.qrae = 0xFF;
if (CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_QDMAREGION_ENABLE, &qraeSetup) !\
= CSL_SOK)
{
LogDebug ("Error: EDMA QDMA region enable command failed\n");
return ERROR;
}
/* QDMA Channel Open (QDMA Channels start after the DMA Channels) */
chAttr.regionNum = coreId;
chAttr.chaNum = 16 + coreId;
hChannel = CSL_edma3ChannelOpen(&chObj, 0, &chAttr, &status);
if ((hChannel == NULL) || (status != CSL_SOK))
{
LogDebug ("Error: EDMA channel open failed\n");
return ERROR;
}
/* Map QDMA Channel to a Param Block */
CSL_edma3HwChannelSetupParam (hChannel, coreId+1);
/* Setup the trigger word for the QDMA Channel. */
if (CSL_edma3HwChannelSetupTriggerWord(hChannel, 4) != CSL_SOK)
{
LogDebug ("Error: EDMA channel setup trigger word failed\n");
return ERROR;
}
/* Parameter Entry Handle */
hParam = CSL_edma3GetParamHandle(hChannel, coreId+1, &status);
if (hParam == NULL)
{
LogDebug ("Error: EDMA get handle for param entry %d failed\n", coreId); \
return -1;
}
paramSetup.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, \
CSL_EDMA3_TCCH_DIS, \
CSL_EDMA3_ITCINT_DIS, \
CSL_EDMA3_TCINT_EN, \
coreId,CSL_EDMA3_TCC_NORMAL, \
CSL_EDMA3_FIFOWIDTH_NONE, \
CSL_EDMA3_STATIC_EN, \
CSL_EDMA3_SYNC_A, \
CSL_EDMA3_ADDRMODE_INCR, \
CSL_EDMA3_ADDRMODE_INCR);
paramSetup.srcAddr = (Uint32)src;
paramSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(256,1);
paramSetup.dstAddr = (Uint32)dst;
paramSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(1,1);
paramSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,1);
paramSetup.cCnt = 1;
/* Setup to operate with this PARAM Entry. */
if (CSL_edma3ParamSetup(hParam, ¶mSetup) != CSL_SOK)
{
LogDebug ("Error: EDMA param setup failed\n");
return ERROR;
}
/* Enable Channel */
if (CSL_edma3HwChannelControl(hChannel, CSL_EDMA3_CMD_CHANNEL_ENABLE, NULL) !\
= CSL_SOK)
{
LogDebug ("Error: EDMA channel enable command failed\n");
return ERROR;
}
/* Close channel */
if (CSL_edma3ChannelClose(hChannel) != CSL_SOK)
{
LogDebug("Error: EDMA channel close failed\n");
return ERROR;
}
/* Close EDMA module */
if (CSL_edma3Close(hModule) != CSL_SOK)
{
LogDebug("Error: EDMA module close failed\n");
return ERROR;
}
return SUCCESS;
}
Int32 QdmaXfer(Uint8 coreId, boolean block)
{
CSL_Edma3ChannelAttr chAttr;
CSL_Edma3ChannelObj chObj;
CSL_Edma3ChannelHandle hChannel;
CSL_Edma3ParamHandle hParam;
CSL_Edma3CmdIntr command;
CSL_Status status;
CSL_Edma3Obj edmaObj;
CSL_Edma3Handle hModule = NULL;
/* QDMA Channel Open */
chAttr.regionNum = coreId;
chAttr.chaNum = 16 + coreId;
hChannel = CSL_edma3ChannelOpen(&chObj, 0, &chAttr, &status);
if ((hChannel == NULL) || (status != CSL_SOK))
{
LogDebug ("Error: EDMA channel open failed\n");
return ERROR;
}
hParam = CSL_edma3GetParamHandle(hChannel, coreId+1, &status);
if (hParam == NULL)
{
LogDebug ("Error: EDMA get handle for param entry 1 failed\n");
return ERROR;
}
/* Trigger the word by writing to the trigger word... */
if (CSL_edma3ParamWriteWord(hParam, 4, 1) != CSL_SOK)
{
LogDebug ("Error: EDMA param write word failed\n");
return ERROR;
}
if (block)
{
/* Module level open */
hModule = CSL_edma3Open(&edmaObj, 0, NULL, &status);
if ((hModule == NULL) || (status != CSL_SOK))
{
LogDebug ("Error: EDMA module open failed\n");
return ERROR;
}
/* Poll IPR bit */
command.region = coreId;
do {
CSL_edma3GetHwStatus(hModule, CSL_EDMA3_QUERY_INTRPEND, &command);
} while (!(command.intr & 0x2));
/* Clear pending interrupt */
if (CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTRPEND_CLEAR, &command) != C\
SL_SOK)
{
LogDebug ("Error: EDMA clear interrupt pend command failed\n");
return ERROR;
}
}
/* Close channel */
if (CSL_edma3ChannelClose(hChannel) != CSL_SOK)
{
LogDebug("Error: EDMA channel close failed\n");
return ERROR;
}
if (hModule)
{
/* Close EDMA module */
if (CSL_edma3Close(hModule) != CSL_SOK)
{
LogDebug("Error: EDMA module close failed\n");
return ERROR;
}
}
return SUCCESS;
}
Int32 QdmaDone(Uint8 coreId)
{
CSL_Edma3Handle hModule;
CSL_Edma3CmdIntr command;
CSL_Status status;
CSL_Edma3Obj edmaObj;
/* Module level open */
hModule = CSL_edma3Open(&edmaObj, 0, NULL, &status);
if ((hModule == NULL) || (status != CSL_SOK))
{
LogDebug ("Error: EDMA module open failed\n");
return ERROR;
}
/* Poll IPR bit */
command.region = coreId;
do {
CSL_edma3GetHwStatus(hModule, CSL_EDMA3_QUERY_INTRPEND, &command);
} while (!(command.intr & (1<<coreId)));
/* Clear pending interrupt */
command.intr = 1 << coreId;
if (CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTRPEND_CLEAR, &command) != C\
SL_SOK)
{
LogDebug ("Error: EDMA clear interrupt pend command failed\n");
return ERROR;
}
return SUCCESS;
}