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.

EDMA Transfer in 8- core processor TMS320C6678

Other Parts Discussed in Thread: TMS320C6678

Hello Everyone,

I want 8 EDMA channels to be utilized simultaneously by 8 cores in TMS320C6678 processor. EDMA channels will be used to transfer data from DDR3 to L2 SRAM of each cores. I am using the example function edma_ping_pong_xfer_gbl_region to transfer data. I tried it for core 0 with channel num equated to DNUM ( or core number (here 0)) and it worked. However when I ran the same code in other cores (channelnum value is 1-7) it didn't work. In fact it worked only when channelnum value is 0, and not for other values (1-7). instnum value is kept 0 for all the cases above.

What are the modifications I need to do to enable 8 EDMA channels to transfer data in 8 cores simultaneously.

Do we require to have 8 different shadow regions to run 8 EDMA channels simultaneously? Then would it be required to use example function edma_ping_pong_xfer_region?

Please clarify the above query as soon as possible

  • Hi,

    Thanks for your post.

    Yes, you would require to use seperate shadow region with each core and need to use different TCC values accordingly for different channels you wish to enable channels accordingly in different shadow regions and generate the shadow region interrupt for each channel based on the completion of transfer.

    Did you start from our EDMA3 LLD examples or are you writing your own drivers?

    Please check the QDMA channel based transfer code, which is using EDMA3 LLD.

    C:\ti\edma3_lld_02_11_05_02\examples\edma3_driver\src

    The best place is to start with the EDMA CSL example source code has portion of the global/shadow region setup for both EDMA/QDMA channel setup, which could be a good reference:

    C:\ti\pdk_C6678_1_1_2_6\packages\ti\csl\example\edma\edma_test.c

    You can take this as a reference code and modify the same accordingly to trigger interrupts and use shadow regions seperately to support multiple core EDMA transfer.

    After you trigger the interrupt in CorePac0, in the ISR of CorePac0, you can continuously trigger the transfer of channel(s) in CorePac 1. Basically, you can trigger the next transfer (CorePac_n+1) in the ISR of CorePac_n. In this way, you do need to enable the same channel(s) in different shadow regions (CorePacs). It may reduce the potential conflict.

    Please ensure to use different TCC values for different cores on memory_transfer()  and in order to initialize the transfer simulataneously on multiple cores, you may need to use different TCC values which associates different DMA channels/bit positions to indicate the transfer completion on the same.

    Also, Kindly ensure the following

    Each core is copying to and from different memory locations (no overlap)

    Each core uses a different channel

    Each core uses a different shadow region

    Each core generates a different EDMA interrupt

    Look at all of the error-related EDMA3 registers, especially SER and EMR and ensure there were no missed events or errors.

    Thanks & regards,

    Sivaraj K

    -------------------------------------------------------------------------------------------------------

    Please click the Verify Answer button on this post if it answers your question.

    -------------------------------------------------------------------------------------------------------

  • Hello

    The code below does EDMA transfer from DDR3 memory to L2 SRAM of each core in TMS320C6678, implemented in CCS software.
    The reference code used is from here - C:\ti\pdk_C6678_1_1_2_6\packages\ti\csl\example\edma\edma_test.c
    I have made the changes in the program and marked them with numbers from 1 to 6.

    1 . One channel in each shadow region , so DRAE bits kept as 0x0000 .

    2. TCC ( Transfer complete code ) value is set according to the channel number ( equal to core number )

    in each shadow region of corresponding cores

    2.2 TCC value used in OPT

    3 IER ( Interrupt enable register ) bits are set as according to TCC values

    4 Is this IER bit

    5 For what purpose is this? Is it required here ?

    6 Is this IPR bit? The bit set in IPR on transfer completion is same as the bit set in IER and TCC too.

    EDMA transfer is not happening on running the code+.

    Please clarify where I am making mistakes and also whether my understanding of the code is right .

    It will be more understandable if you explain everything number-wise.

    Thanks and regards

    Anamika


    /////////////////////// ..................... START ....................//////////////////
    #include <stdio.h>
    #include <math.h>
    #include <stdlib.h>
    #include <time.h>
    #include <csl_edma3.h>
    #include <csl_edma3Aux.h>
    #include <csl_cacheAux.h>
    extern cregister volatile unsigned int DNUM;

    #pragma DATA_ALIGN(src1, 8);
    #pragma DATA_SECTION (src1 , ".data4")
    float src1[1000];

    #pragma DATA_ALIGN(dst1, 8);
    #pragma DATA_SECTION (dst1 , ".data")
    float *dst1;

    unsigned int numProc;
    Uint8 channelNum;
    Int32 regionNum;
    Uint8 instNum;
    /**********************************************************************
    ************************** Global Variables **************************
    **********************************************************************/

    /* Global Variables which are used to dump the TPCC register overlay in the
    * debugger... */
    CSL_TpccRegs* gEDMACC0Regs = (CSL_TpccRegs*)CSL_EDMA0CC_REGS;
    CSL_TpccRegs* gEDMACC1Regs = (CSL_TpccRegs*)CSL_EDMA1CC_REGS;
    CSL_TpccRegs* gEDMACC2Regs = (CSL_TpccRegs*)CSL_EDMA2CC_REGS;

    unsigned int g_Add, TCC, IERb;

    int main(void)
    {
    numProc=DNUM;
    int i;

    CSL_Edma3Handle hModule;
    CSL_Edma3Obj edmaObj;
    CSL_Edma3ParamHandle hParamPing;
    CSL_Edma3ChannelObj chObj;
    CSL_Edma3CmdIntr regionIntr;
    CSL_Edma3CmdDrae regionAccess;
    CSL_Edma3ChannelHandle hChannel;
    CSL_Edma3ParamSetup myParamSetup;
    CSL_Edma3Context context;
    CSL_Edma3ChannelAttr chAttr;
    CSL_Status status;



    instNum=0;


    /* Start the EDMA PING-PONG test over the Shadow Region. */
    printf ("Debug: Testing EDMA(%d) Ping-Pong Test Shadow-Region %d for Channel %d...\n", instNum, regionNum, channelNum);

    /* Module Initialization */
    if (CSL_edma3Init(&context) != CSL_SOK)
    {
    printf ("Error: EDMA module initialization failed\n");
    }

    /* Module level open */
    hModule = CSL_edma3Open(&edmaObj, instNum, NULL, &status);
    if ((hModule == NULL) || (status != CSL_SOK))
    {
    printf ("Error: EDMA module open failed\n");
    }

    /* Determine the number of channels we need to enable. Is this Instance 0? */
    if (instNum == 0)
    {

    /* YES. DRAE enable(Bits 0-15) for the shadow region; since there are 16 channels. */
    regionAccess.region = numProc;
    regionAccess.drae = 0x0000; /////////////////////////////.................... 1 ......................... ///////////////////////////////////////
    regionAccess.draeh = 0x0;
    if (CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_DMAREGION_ENABLE, &regionAccess) != CSL_SOK)
    {
    printf ("Error: EDMA region enable command failed\n");
    }
    }
    else
    {
    /* YES. DRAE enable(Bits 0-63) for the shadow region; since there are 64 channels. */
    regionAccess.region = numProc;
    regionAccess.drae = 0x00000000;
    regionAccess.draeh = 0x00000000;
    if (CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_DMAREGION_ENABLE, &regionAccess) != CSL_SOK)
    {
    printf ("Error: EDMA region enable command failed\n");
    }
    }

    switch(numProc)
    {
    case 0:
    g_Add=0x10000000;
    TCC=0x000000; //////////////////// ..................... 2 .................. ///////////////////
    IERb=0x0000; ///////////////// ..................... 3 ................... //////////////
    break;

    case 1:
    g_Add=0x11000000;
    TCC=0x000001;
    IERb=0x0001;
    break;

    case 2:
    g_Add=0x12000000;
    TCC=0x000002;
    IERb=0x0002;
    break;

    case 3:
    g_Add=0x13000000;
    TCC=0x000003;
    IERb=0x0003;
    break;

    case 4:
    g_Add=0x14000000;
    TCC=0x000004;
    IERb=0x0004;
    break;

    case 5:
    g_Add=0x15000000;
    TCC=0x000005;
    IERb=0x0005;
    break;

    case 6:
    g_Add=0x16000000;
    TCC=0x000006;
    IERb=0x0006;
    break;

    case 7:
    g_Add=0x17000000;
    TCC=0x000007;
    IERb=0x0007;
    break;
    }

    /* Interrupt enable (Bits 0-11) for the shadow region 5 */
    regionIntr.region = numProc;
    regionIntr.intr = IERb; /////////////////////// ..................... 4 ................... /////////////////////////
    regionIntr.intrh = 0x0000;

    if (CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTR_ENABLE, &regionIntr) != CSL_SOK)
    {
    printf ("Error: EDMA interrupts enable command failed\n");
    }

    /* Open the channel in context of the specified region number. */
    chAttr.regionNum = numProc;
    chAttr.chaNum = numProc;
    hChannel = CSL_edma3ChannelOpen(&chObj, instNum, &chAttr, &status);
    if ((hChannel == NULL) || (status != CSL_SOK))
    {
    printf ("Error: EDMA channel open failed\n");
    }

    /* Map the DMA Channel to the appropriate PARAM Block. We start with PING
    * which is located at PARAM Block 2. */
    if (CSL_edma3HwChannelSetupParam(hChannel, 2) != CSL_SOK)
    {
    printf ("Error: EDMA channel setup param failed\n");
    }

    /* Obtain a handle to parameter set 2 */
    hParamPing = CSL_edma3GetParamHandle(hChannel, 2, &status);
    if (hParamPing == NULL) {
    printf ("Error: EDMA get param handle for param entry 2 failed\n");
    }

    dst1 = (float*)malloc((1000)*sizeof(float));

    for(i=0;i<1000;i++)
    {
    src1[i]=i;
    dst1[i]=0;
    }


    /* Setup the first param set (Ping buffer) */
    myParamSetup.option = CSL_EDMA3_OPT_MAKE( CSL_EDMA3_ITCCH_DIS, \
    CSL_EDMA3_TCCH_DIS, \
    CSL_EDMA3_ITCINT_EN, \
    CSL_EDMA3_TCINT_EN,\
    TCC,\
    CSL_EDMA3_TCC_NORMAL,\
    CSL_EDMA3_FIFOWIDTH_NONE, \
    CSL_EDMA3_STATIC_DIS, \
    CSL_EDMA3_SYNC_AB, \
    CSL_EDMA3_ADDRMODE_INCR, \
    CSL_EDMA3_ADDRMODE_INCR
    ); ///////////////// ................. 2.2 ..................//////////////////////
    myParamSetup.srcAddr = (Uint32)src1;
    myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(4,1000);
    myParamSetup.dstAddr = (Uint32)dst1+g_Add;
    myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(4,4);
    myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(4000,4);
    myParamSetup.cCnt = 1;

    /* Setup the Ping Entry which loaded after the Pong entry gets exhausted */
    if (CSL_edma3ParamSetup(hParamPing,&myParamSetup) != CSL_SOK)
    {
    printf("Error: EDMA ping parameter entry setup is failed\n");
    }

    /* Enable channel */
    if (CSL_edma3HwChannelControl(hChannel,CSL_EDMA3_CMD_CHANNEL_ENABLE, NULL) != CSL_SOK)
    {
    printf("Error: EDMA channel enable command is failed\n");
    }
    /* Mapping channel 0 to event queue 1 */
    if (CSL_edma3HwChannelSetupQue(hChannel,CSL_EDMA3_QUE_1) != CSL_SOK) ///////////////////// ..........5 ................////////////////
    {
    printf("Error: EDMA channel setup queue is failed\n");
    }

    /* Manually trigger the channel */
    if (CSL_edma3HwChannelControl(hChannel,CSL_EDMA3_CMD_CHANNEL_SET,NULL) != CSL_SOK)
    {
    printf("Error: EDMA channel set command is failed\n");
    }


    regionIntr.region = numProc;
    regionIntr.intr = 0; //////////////////// ........... 6................ //////////////////////////////////////
    regionIntr.intrh = 0;

    do {
    /* Poll on interrupt bit 0 */
    CSL_edma3GetHwStatus(hModule,CSL_EDMA3_QUERY_INTRPEND,&regionIntr);// is this IPR
    } while (!(regionIntr.intr & 0x1));

    /* Clear interrupt bit 0 */
    if (CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTRPEND_CLEAR, &regionIntr) != CSL_SOK)
    {
    printf("Error: EDMA clear interrupt bit 0 command is failed\n");
    }


    /* Close channel */
    if (CSL_edma3ChannelClose(hChannel) != CSL_SOK)
    {
    printf("Error: EDMA channel close failed\n");
    }

    /* Close EDMA module */
    if (CSL_edma3Close(hModule) != CSL_SOK)
    {
    printf("Error: EDMA module close failed\n");
    }

    /* Test Passed. */
    return 0;
    }

    ////////////////////////////////////////////////////////// ................. END ................. /////////////////////////////////////////////////////////////