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.

C6455的EDMA3同步传输大量数据到DDR2,后半部分数据传输失败



EDMA3从FPGA的FIFO中一次同步传输200K字节到DDR2,确认ddr2的存储没有问题,发现后半部分数据传输失败,请问是什么原因?当一次传输数据减小到20K字节的时候传输成功。EDMA3的配置代码如下:

myParamSetup.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, \
                                             CSL_EDMA3_TCCH_DIS, \
                                             CSL_EDMA3_ITCINT_DIS, \
                                             CSL_EDMA3_TCINT_EN,\
                                             1,CSL_EDMA3_TCC_NORMAL,\
                                             CSL_EDMA3_FIFOWIDTH_32BIT, \
                                             CSL_EDMA3_STATIC_DIS, \
                                             CSL_EDMA3_SYNC_A, \
                                             CSL_EDMA3_ADDRMODE_INCR, \
                                             CSL_EDMA3_ADDRMODE_INCR);
    myParamSetup.srcAddr = (Uint32)srcBuff;         
     myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(100000*4,1);
    myParamSetup.dstAddr = (Uint32)dstBuff4;       
    myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(0,0);    
    myParamSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE (CSL_EDMA3_LINK_NULL,
                                                           1);
    myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,0);    
    myParamSetup.cCnt = 1;         

  • FIFO的宽度是3000个字节,FPGA写FIFO数据的频率是54MHz,EMIFA的读数频率是55.556MHz,略快于FIFO的写数频率
  • ACNT的最大值是65535。

  • 假如我一次EDMA传输要写200K字节,怎样设置ACNT、BCNT、CCNT呢?传输数据量大是否要设置为AB同步模式传输?
  • 用A和AB模式都可以,只是要注意的是ACNT, BCNT, CCNT最大值都不能超过64k。
  • 我将设置改为myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(12000*4,6);使用A模式,开始运行后一直等待传输中断完成,请问是什么原因?
  • /* Module initialization */
    status = CSL_edma3Init(&context);
    if (status != CSL_SOK) {
    printf ("Edma module initialization failed\n");
    return;
    }
    //printf("edma interrupt\n");
    /* Intc module initialization */
    intcContext.eventhandlerRecord = EventHandler;
    intcContext.numEvtEntries = 10;
    CSL_intcInit(&intcContext);

    /* Enable NMIs */
    CSL_intcGlobalNmiEnable();

    /* Enable global interrupts */
    CSL_intcGlobalEnable(&state);

    /* Opening a intc handle for edma event */
    vectId = CSL_INTC_VECTID_4;
    hIntcEdma = CSL_intcOpen (&intcObjEdma, CSL_INTC_EVENTID_EDMA3CC_INT1, \
    &vectId , NULL);

    /* Edma module open */
    hModule = CSL_edma3Open(&edmaObj,CSL_EDMA3,NULL,&status);
    if ( (hModule == NULL) || (status != CSL_SOK)) {
    printf ("Edma module open failed\n");
    return;
    }

    /* Edma module setup */
    dmahwSetup.paramNum = 0;
    dmahwSetup.que = CSL_EDMA3_QUE_0;
    hwSetup.dmaChaSetup = &dmahwSetup;
    hwSetup.qdmaChaSetup = NULL;
    status = CSL_edma3HwSetup(hModule,&hwSetup);
    if (status != CSL_SOK) {
    printf ("Hardware setup failed\n");
    CSL_edma3Close (hModule);
    return;
    }

    /* Setup the DRAE masks
    * DRAE enable(Bits 0-15) for the shadow region 1.
    */
    regionAccess.region = CSL_EDMA3_REGION_1 ;
    regionAccess.drae = 0xFFFF ;
    regionAccess.draeh = 0x0000 ;
    status = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_DMAREGION_ENABLE, \
    &regionAccess);
    if (status != CSL_SOK) {
    printf("Edma region enable command failed\n");
    return;
    }

    /* Channel open */
    chAttr.regionNum = CSL_EDMA3_REGION_1;
    chAttr.chaNum = CSL_EDMA3_CHA_DSP_EVT;
    hChannel = CSL_edma3ChannelOpen(&chObj, CSL_EDMA3, &chAttr, &status);
    if ( (hChannel == NULL) || (status != CSL_SOK)) {
    printf ("Edma channel open failed\n");
    return;
    }

    /* Get the parameter handle */
    hParamBasic = CSL_edma3GetParamHandle(hChannel,0,&status);
    if (hParamBasic == NULL) {
    printf("Edma get param handle failed\n");
    return;
    }
    myParamSetup.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, \
    CSL_EDMA3_TCCH_DIS, \
    CSL_EDMA3_ITCINT_DIS, \
    CSL_EDMA3_TCINT_EN,\
    1,CSL_EDMA3_TCC_NORMAL,\
    CSL_EDMA3_FIFOWIDTH_32BIT, \
    CSL_EDMA3_STATIC_DIS, \
    CSL_EDMA3_SYNC_A, \
    CSL_EDMA3_ADDRMODE_INCR, \
    CSL_EDMA3_ADDRMODE_INCR);
    myParamSetup.srcAddr = (Uint32)srcBuff;
    myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(8000*4,4);
    myParamSetup.dstAddr = (Uint32)dstBuff4;
    myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(0,0);
    myParamSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE (CSL_EDMA3_LINK_NULL,
    1);
    myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,0);
    myParamSetup.cCnt = 1;
    status = CSL_edma3ParamSetup(hParamBasic,&myParamSetup);
    if (status != CSL_SOK) {
    printf ("Edma param setup failed\n");
    return;
    }

    /* Association of an EDMA event handler with the INTC routine */
    EventRecord.handler = &eventEdmaHandler;
    EventRecord.arg = (void*)(hModule);
    CSL_intcPlugEventHandler(hIntcEdma,&EventRecord);

    /* Enabling event edma */
    CSL_intcHwControl(hIntcEdma,CSL_INTC_CMD_EVTENABLE,NULL);

    /* Hook up the EDMA event with an completion code function handler */
    EdmaEventHook(1, tcc1Fxn);

    /* Enable interrupts */
    regionIntr.region = CSL_EDMA3_REGION_1 ;
    regionIntr.intr = 0x2 ;
    regionIntr.intrh = 0x0 ;
    status = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTR_ENABLE,&regionIntr);
    if (status != CSL_SOK) {
    printf ("Edma interrupt enable command failed\n");
    return;
    }
    /* Manually trigger the channel */
    status = CSL_edma3HwChannelControl(hChannel,CSL_EDMA3_CMD_CHANNEL_SET,NULL);
    if (status != CSL_SOK) {
    printf ("Edma channel set command failed\n");
    return;
    }
    /* Wait for completion */
    while (!intFlag);
    /* Disable the region 1 access */
    regionAccess.region = CSL_EDMA3_REGION_1 ;
    regionAccess.drae = 0xFFFF ;
    regionAccess.draeh = 0x0000 ;
    status = CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_DMAREGION_DISABLE, \
    &regionAccess);

    运行上述代码一直卡在 while (!intFlag); 上等待传输完成中断触发,请问是什么原因?