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 Hwi problem

Other Parts Discussed in Thread: TMS320C6678, SYSBIOS

Hello,

i have an issue. I use tms320c6678. EDMA doesn't send an interrupt when EDMA transfer comple. When I use polling everything ok but interrupt doesn't came to my hwi_handler.

I setup channel 2 to region 1, set TCC to 0x1, enable IESR. But it doesn't work. IPR=0x2, IER=0x2, DRAE=0xFFFF. What should I do for receive hwi from EDMA?   

  • Ilya,

    Your questions seems to be specific to the device's DMA peripheral rather than with BIOS, so I have moved this thread over to the device forum in hopes that you will get a faster response there.

  • Hi,

    check this example (can be found in chip support installation directory), you need to use the chip-interrupt controller (CIC) instance 0 is used to map system- to host interrupts.

    If you're using SysBios you only need to configure what is done in the function cp_intc_config()


    #include <stdio.h>
    #include <ti/csl/csl.h>
    #include <ti/csl/soc.h>
    #include <ti/csl/csl_edma3.h>
    #include <ti/csl/csl_edma3Aux.h>
    #include <ti/csl/src/intc/csl_intc.h>
    #include <ti/csl/csl_cpintc.h>
    #include <ti/csl/csl_cpintcAux.h>

    CSL_IntcHandle   hIntc;
    CSL_CPINTC_Handle hnd;

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

    volatile unsigned int flag = 0;


    static void edma_isr_handler (void* handle)
    {

     CSL_CPINTCHostInterrupt       hostIntr = 40;
     CSL_CPINTCSystemInterrupt     sysIntr = 6;


     /* Disable CPINTC0 Host interrupt (CPINTC output) */
     CSL_CPINTC_disableHostInterrupt(hnd, hostIntr);

     /* Clear the CPINTC0 Interrupt */
     CSL_CPINTC_clearSysInterrupt(hnd, sysIntr);

     /* Clear the CorePac Interrupt */
     CSL_intcHwControl(hIntc,CSL_INTC_CMD_EVTCLEAR,NULL);

     /* ISR EVENTUAL TASKS */

        /* Clear the pending bit */
        CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTRPEND_CLEAR,&regionIntr);

     flag++;

     /* ****************** */

     /* Enable CPINTC0 Host interrupt (CPINTC output) */
     CSL_CPINTC_enableHostInterrupt(hnd, hostIntr);

    }

    void gem_intc_config( void ){

     CSL_IntcContext             intcContext;
     CSL_IntcGlobalEnableState   state;
     CSL_IntcObj                 intcObj;
     CSL_IntcParam               vectId;
     CSL_IntcEventHandlerRecord  EventRecord;
     CSL_IntcEventHandlerRecord  EventHandler[30];

     intcContext.eventhandlerRecord = EventHandler;
     intcContext.numEvtEntries      = 10;

     /* Initiate INTC module */
     CSL_intcInit(&intcContext);

     /* Enable NMIs : Non Maskable Interrups*/
            CSL_intcGlobalNmiEnable() ;

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

     /* Open the INTC Module for Vector ID: 4 and Event ID: 29 (C6678) */
            /* Instance 1 (EDMACC1), Core 0 */

     vectId = CSL_INTC_VECTID_4;
     hIntc = CSL_intcOpen (&intcObj, 29, &vectId , NULL);

     /* Register an call-back handler which is invoked when the event occurs. */
     EventRecord.handler = &edma_isr_handler;
     EventRecord.arg = 0;

     CSL_intcPlugEventHandler(hIntc,&EventRecord);

     /* Enabling the events. */
     CSL_intcHwControl(hIntc,CSL_INTC_CMD_EVTENABLE, NULL);
    }

     


    void cp_intc_config( void ){

     // chip-level INTC0 is for CorePac0~3
     hnd = CSL_CPINTC_open(CSL_CP_INTC_0); // edma3 events are mapped to CPINTC0

     /* Disable all host interrupts. */
     CSL_CPINTC_disableAllHostInterrupt(hnd);

     /* Configure no nesting support in the CPINTC Module. */
     CSL_CPINTC_setNestingMode (hnd, CPINTC_NO_NESTING);

     /* Map System Interrupt 6 (EDMACC GINT) to channel 40 */
     CSL_CPINTC_mapSystemIntrToChannel (hnd, 6, 40);

      /* Map channel 40 to host interrupt 40 */
     //CSL_CPINTC_mapChannelToHostInterrupt (hnd, 40 , 40);

     /* Enable system interrupt 6 */
     CSL_CPINTC_enableSysInterrupt (hnd, 6);

     /* We enable host interrupts. */
     CSL_CPINTC_enableHostInterrupt (hnd, 40);

     /* Enable all host interrupts also. */
     CSL_CPINTC_enableAllHostInterrupt(hnd);

    }

     

     

     


    int Edma_block_transfer(float* block_src, float* block_dst)
    {

     


    Uint8 coreNum = 0;

    Int32 instNum = 1;

    Uint8 channelNum = 1;
     unsigned int ACNT = 128;
     unsigned int BCNT = 1;
     unsigned int CCNT = 1;
     unsigned int SRCBIDX = 0;
     unsigned int DSTBIDX = 0;

        // instNum = 1; -> p161/232 data manual EDMACC1_GINT is tied to Event #6

     Uint32 L2Offset;
     L2Offset = 0x10000000 + coreNum*0x01000000;

        /* Module initialization            */
        CSL_edma3Init(&context) ;

        /* Open the EDMA Module using the instance number      */

        hModule = CSL_edma3Open(&edmaObj, instNum, NULL, &status);

        /* Channel Open Global              */
        chAttr.regionNum = CSL_EDMA3_REGION_GLOBAL;
        chAttr.chaNum    = channelNum;

        hChannel = CSL_edma3ChannelOpen(&chObj, instNum, &chAttr, &status);

        /* Map the DMA Channel to the appropriate PARAM Block.       */
        CSL_edma3HwChannelSetupParam(hChannel, 1) ;

        /* Obtain a handle to parameter set           */
        hParamBlock1 = CSL_edma3GetParamHandle(hChannel, 1, &status);


        /* Setup the param set                 */
        myParamSetup.option = CSL_EDMA3_OPT_MAKE( CSL_EDMA3_ITCCH_DIS, \
                                                  CSL_EDMA3_TCCH_DIS, \
                                                  CSL_EDMA3_ITCINT_DIS, \
                                                  CSL_EDMA3_TCINT_EN, \
                                                  6, \
                                                  CSL_EDMA3_TCC_NORMAL, \
                                                  CSL_EDMA3_FIFOWIDTH_NONE, \
                                                  CSL_EDMA3_STATIC_EN, \
                                                  CSL_EDMA3_SYNC_A, \
                                                  CSL_EDMA3_ADDRMODE_INCR, \
                                                  CSL_EDMA3_ADDRMODE_INCR
                                                 );

          myParamSetup.srcAddr    = (Uint32)block_src;
          myParamSetup.dstAddr    = (Uint32)block_dst + L2Offset; // Global adress needed
          myParamSetup.aCntbCnt   = CSL_EDMA3_CNT_MAKE(ACNT,BCNT);
          myParamSetup.cCnt       = CCNT;
          myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(SRCBIDX,DSTBIDX);
          myParamSetup.linkBcntrld= CSL_EDMA3_LINKBCNTRLD_MAKE(CSL_EDMA3_LINK_NULL,0);
          myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,0);

        /* Setup the block1 entry */
        CSL_edma3ParamSetup(hParamBlock1,&myParamSetup);

        /* Interrupt enable for the global region interrupts */
       regionIntr.region = CSL_EDMA3_REGION_GLOBAL;
       regionIntr.intr = (1<<6);
       regionIntr.intrh = 0;
        CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTR_ENABLE,&regionIntr);

        /* *************************************************************************** */
        /* Manually trigger the channel 1               */
        /* *************************************************************************** */
     CSL_edma3HwChannelControl(hChannel,CSL_EDMA3_CMD_CHANNEL_SET,NULL);

     /* ISR */

     /* Close channel                   */
     //CSL_edma3ChannelClose(hChannel);

     /* Close EDMA module                  */
        //CSL_edma3Close(hModule);
    }


    void main(void) {

     float * block_src = NULL;
     float * block_dst = NULL;

     block_src = (float *)0x10840000;
     block_dst = (float *)0x00850000;

     gem_intc_config();

     cp_intc_config();

     Edma_block_transfer(block_src, block_dst);

     while (flag != 1) {
      printf("wait for flag = 1\n");
     }

     printf ("ISR has been completed 1st time\n");

     /* Close channel                   */
     CSL_edma3ChannelClose(hChannel);

     /* Close EDMA module                  */
     CSL_edma3Close(hModule);

     Edma_block_transfer(block_src, block_dst);


     while (flag != 2) {
      printf ("wait for flag = 2\n");
     }
     printf ("ISR has been completed 2nd time\n");

     /* Close channel                   */
     CSL_edma3ChannelClose(hChannel);

     /* Close EDMA module                  */
     CSL_edma3Close(hModule);

    }

     best regards

     

    Pay Gießelmann

  • Thank you, that works fine for EDMA3CC1 controller, but I cannot set DRAEH/IERH registers for use EDMA3CC0 (for setup IER 36 interrupt event).

  • to Pay:

       there might be some bugs in this code, that on my EVMC6678L board the interrupt can just be posted once. for the second time of the EDMA transfer, CPU hangs.

       you should add interrupt init process before the second EDMA transfer.

       gem_intc_config();

        cp_intc_config();

    so it seems that after the first EDMA transfer or during the first ISR run, the interrupt configuration is changed.