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; }