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.

TMS320C6654: EDMA3 transfer

Part Number: TMS320C6654

Hi,

The customer want to enable edma transfer between dsp and fpga. He can transfer successfully by channel 0. And when he change channel number to 1, the program can not enter into interrupt and param do not update as well when submit a TR. He just modify channel number, any other parameters need to change?

Below is the related code:

unsigned int chType     = EDMA3_CHANNEL_TYPE_DMA;
unsigned int chNum      = 0;
unsigned int tccNum     = 0;
unsigned int edmaTC     = 0;
unsigned int syncType   = EDMA3_SYNC_A;
unsigned int trigMode   = EDMA3_TRIG_MODE_MANUAL;
unsigned int evtQ       = 0;
EDMA3CCPaRAMEntry paramSet;
//unsigned int edma_paRAMId1 = 1;
//unsigned int edma_paRAMId2 = 2;
unsigned int transfer_times = 0;   
volatile char *srcBuff;
volatile char *dstBuff;
unsigned short emif_wbuffer[EMIF_BUFFER_LENGTH];
unsigned short emif_rbuffer[EMIF_BUFFER_LENGTH];
unsigned short temp_rbuffer[EMIF_BUFFER_LENGTH];
void fpga_emif16_edma_test(void)
{
    volatile unsigned int status = FALSE;
    printf("EMIF EDMA testing...\r\n");
    EDMA3Init(SOC_EDMA30CC_0_REGS, evtQ);
    EDMA3InterruptInit();
    unsigned int i = 0;
    
    for (i = 0; i < EMIF_BUFFER_LENGTH; i++)
    {
        emif_wbuffer[i] = (unsigned short)(i+15);
        emif_rbuffer[i] = 0xEFEF;
    }
    emif_wbuffer[0] = 0;
    emif_wbuffer[EMIF_BUFFER_LENGTH-1] = 0;
    /*向FPGA写数据*/
    printf( "Reading %d words from FPGA\r\n", EMIF_BUFFER_LENGTH );
    srcBuff = (char *)(SOC_EMIFA_CS1_ADDR);
    dstBuff = (char *)(emif_rbuffer);
    edma_test();
    volatile unsigned int EMIFA_error_count = 0;
    
    printf("Checking data...\n");
    for (i = 0; i<EMIF_BUFFER_LENGTH; i++)
    {
        if (emif_wbuffer[i] != emif_rbuffer[i])
        {
            EMIFA_error_count++;
        }
    }
    
    if (EMIFA_error_count)
    {
        printf( "EMIFA_error_count=%d\n", EMIFA_error_count);
        while(1);
    }
    else
    {
        printf("All data read successful!\n");
        printf("EMIFA transfers complete!\n");
    }
    while(1);
}
 
unsigned int edma_test(void)
{
    volatile unsigned int index = 0;
    volatile unsigned int count = 0;
    unsigned int retVal = 0u;
    unsigned int numenabled = 0u;
    unsigned int acnt = MAX_ACOUNT;
    unsigned int bcnt = MAX_BCOUNT;
    unsigned int ccnt = MAX_CCOUNT;
    
    retVal = EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, chType, chNum, tccNum, evtQ);
    
    cb_Fxn[tccNum] = &callback;
    if (TRUE == retVal)
    {
        /*Set params for channel 0*/
        
        paramSet.srcAddr    = (unsigned int)(srcBuff);
        paramSet.destAddr   = (unsigned int)(dstBuff);
        paramSet.aCnt = (unsigned short)acnt;
        paramSet.bCnt = (unsigned short)bcnt;
        paramSet.cCnt = (unsigned short)ccnt;
       
        paramSet.srcBIdx = (short)acnt;
        paramSet.destBIdx = (short)acnt;
        paramSet.srcCIdx = (short)acnt;
        paramSet.destCIdx = (short)acnt;
        //paramSet.linkAddr = (unsigned short)EDMA3CC_OPT(edma_paRAMId1);
        paramSet.linkAddr = (unsigned short)0xFFFFu;
        paramSet.bCntReload = (unsigned short)0u;
        paramSet.opt = 0u;
        
        paramSet.opt &= 0xFFFFFFFCu;
        // Transfer complete chaining enable
        //        paramSet.opt |= ((1 << EDMA3CC_OPT_TCCHEN_SHIFT) & EDMA3CC_OPT_TCCHEN);
        // Intermediate transfer completion interrupt enable
        //        paramSet.opt |= ((1 << EDMA3CC_OPT_ITCCHEN_SHIFT) & EDMA3CC_OPT_ITCCHEN);
        
        paramSet.opt |= ((tccNum << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC);
        
        paramSet.opt |= (1 << EDMA3CC_OPT_ITCINTEN_SHIFT);
        paramSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT);
       
        paramSet.opt &= 0xFFFFFFFBu;
        
        EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, chNum, &paramSet);
        /*Set params for edma_paRAMId1*/
//        paramSet.linkAddr = (unsigned short)EDMA3CC_OPT(edma_paRAMId1);
//        EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, edma_paRAMId1, &paramSet);
        /*Set params for edma_paRAMId2*/
        //        paramSet.linkAddr = (unsigned short)EDMA3CC_OPT(edma_paRAMId1);
        //        EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, edma_paRAMId2, &paramSet);
    }
    if (TRUE == retVal)
    {
        
        numenabled = bcnt * ccnt;
        transfer_times = 0;
        
        global.last_timer = global.timer;
        for (index = 0; index < numenabled; index++)
        {
            irqRaised = 0;
            
            retVal = EDMA3EnableTransfer(SOC_EDMA30CC_0_REGS, chNum, EDMA3_TRIG_MODE_MANUAL);
            if (TRUE != retVal)
            {
                printf("edma3Test: EDMA3EnableTransfer Failed.\r\n");
                break;
            }
            
            while (irqRaised == 0u)
            {
            }
            
            if (irqRaised < 0)
            {
                
                printf("\r\nedma3Test: Event Miss Occured!!!\r\n");
                
                EDMA3ClearErrorBits(SOC_EDMA30CC_0_REGS, chNum, evtQ);
                break;
            }
        }
        printf("The rate of emif_edma_rate is %02fM/s.\r\n", (float)EMIF_BUFFER_LENGTH*TEST_TIMES/((global.timer - global.last_timer)*1000));
        //            EDMA3EnableTransfer(SOC_EDMA30CC_0_REGS, chNum, EDMA3_TRIG_MODE_MANUAL);
    }
    if (TRUE == retVal)
    {
        
        retVal = EDMA3FreeChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA, chNum, EDMA3_TRIG_MODE_MANUAL, tccNum, evtQ);
        
        cb_Fxn[tccNum] = NULL;
    }
    return retVal;
}
  • Hi Nancy,

    For C6654, http://www.ti.com/lit/ds/symlink/tms320c6654.pdf, There are 4 EDMA TCs (Table 6-24. EDMA3 Transfer Controller Configuration). Given the FPGA is connected to EMIF interface, any TC should work.

    unsigned int chType     = EDMA3_CHANNEL_TYPE_DMA;
    unsigned int chNum      = 0; ===============>If you changed this to 1
    unsigned int tccNum     = 0; ===============> change this to 1 as well
    unsigned int edmaTC     = 0; ===============> change this to 1 as well
    unsigned int syncType   = EDMA3_SYNC_A;
    unsigned int trigMode   = EDMA3_TRIG_MODE_MANUAL;
    unsigned int evtQ       = 0; ===============> change this to 1 as well

    Let me know if this works.

    Regards, Eric

  • Hi,

    Thanks! The problem has been solved. He didn't clear interrupt.

    Another question about the channel and param.

    The first n PaRAM sets are directly mapped to the DMA channels (where n is the number of DMA channels supported in the EDMA3CC for a specific device). 

    By default, all channels map to PaRAM set 0. These should be re-mapped before use.


    Does it mean channel 1 can map to any PaRAM(from 0~63), they are not fixed?

  • Hi,

    Good to know the issue was resolved. For ParamSets to DMA channel mapping, they are not fixed and it is controlled by DCHMAP registers.

    From EDMA user guide:

    By default, all channels map to PaRAM set 0. These should be re-mapped before use. See Section 4.2.1.3 (DCHMAP registers) and Section 4.2.1.4 (QCHMAP registers) for more information.

    For example, you may have 512 groups of PaRAM set, but you only have 64 DMA channels. See below code snippet:

    /* Map PaRAM set to DMA channel */

    DEVICE_REG32_W(edmaBase + 0x108, 100<<5); ===========> Then you use ParamSets 100 (0 based) for DMA channel 2 (0 based, register offset starts from 0x100. 0x100 is for DMA channel 0, 0x104 is for DMA channel 1, 0x108 is for DMA channel 2, etc....). 

    Regards, Eric