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.

Multiple QDMA transfers

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, &regionAccess\
) != 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, &paramSetup) != 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; }