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 MCBSP

Hi,

we have a problem with edma3 and mcbsp in a dsp-bios application.

The tdm stream in composed by 64 slot, 8 bit, external clock and frame sync (2.048MHz and 4KHz respectively). Data and FS are posedge aligned with clock

we use CSL  in C6455_default_package to configure EDMA and MCBSP.

We started with "edma_ping_pong_xfer_gbl_reg" example, then we added mcbsp configuration and we used dsp bios to manage hw int from edma

we divide each ping-buffer in 64 buffer of 40 byte for each slot

We notice that in transmit direction, the data output of the mcbsp is one slot in advance (so the data of first buffer is trasmitted in the slot before the frame sync, the data of the second buffer is trasmitted in the same slot of FS and so on)

In the receive direction, instead, we have a similar problem but with an opposite effect. The data received form the mcbsp are one slot in later.

this is my toolchain:

CCS 3.3.46.1

BIOS 5.31.02

CSL 03.00.10.02

this is my mcbsp configuration:

/*  Receive data setup */                                       
CSL_McbspDataSetup rcvDataCfg = {                            
    CSL_MCBSP_PHASE_SINGLE,                                   
    CSL_MCBSP_WORDLEN_8,                                     
    64,                             /* FRMLEN1 */
    CSL_MCBSP_WORDLEN_8,            /* Default value for phase2*/
    0,                              /* FRMLEN2 */                                                    
    CSL_MCBSP_FRMSYNC_IGNORE,
    //CSL_MCBSP_FRMSYNC_DETECT,                                
    CSL_MCBSP_COMPAND_OFF_MSB_FIRST,                          
    CSL_MCBSP_DATADELAY_0_BIT,
    CSL_MCBSP_RJUSTDXENA_RJUST_RZF,
    CSL_MCBSP_INTMODE_ON_FSYNC,
    //CSL_MCBSP_INTMODE_ON_READY,          
    CSL_MCBSP_32BIT_REVERS_DISABLE
};                          
                                  
/*  Transmit data setup */                            
CSL_McbspDataSetup xmtDataCfg = {                            
    CSL_MCBSP_PHASE_SINGLE,                                   
    CSL_MCBSP_WORDLEN_8,                                     
    64,                  /* FRMLEN1 */
    CSL_MCBSP_WORDLEN_8, /* Default value */                                         
    0,                   /* FRMLEN2 */                                                        
    CSL_MCBSP_FRMSYNC_IGNORE,
    //CSL_MCBSP_FRMSYNC_DETECT,                                 
    CSL_MCBSP_COMPAND_OFF_MSB_FIRST,                          
    CSL_MCBSP_DATADELAY_0_BIT,                                
    CSL_MCBSP_RJUSTDXENA_DXENA_OFF,
    CSL_MCBSP_INTMODE_ON_FSYNC,
    //CSL_MCBSP_INTMODE_ON_READY,                     
    CSL_MCBSP_32BIT_REVERS_DISABLE
};                       
 
/*  Mcbsp clock setup */                                   
CSL_McbspClkSetup clkCfg = {                                          
    CSL_MCBSP_FSCLKMODE_EXTERNAL,//CSL_MCBSP_FSCLKMODE_INTERNAL,    /* XMT Frame-sync */             
    CSL_MCBSP_FSCLKMODE_EXTERNAL,//CSL_MCBSP_FSCLKMODE_INTERNAL,    /* RCV Frame-sync */             
    CSL_MCBSP_TXRXCLKMODE_EXTERNAL,//CSL_MCBSP_TXRXCLKMODE_INTERNAL,  /* XMT clock */                      
    CSL_MCBSP_TXRXCLKMODE_EXTERNAL,//CSL_MCBSP_TXRXCLKMODE_INTERNAL,  /* RCV clock */                      
    CSL_MCBSP_FSPOL_ACTIVE_HIGH,     /* XMT Frame-sync Active High */               
    CSL_MCBSP_FSPOL_ACTIVE_HIGH,     /* RCV Frame-sync Active High */               
    CSL_MCBSP_CLKPOL_TX_RISING_EDGE, /* XMT clock Rising Edge */                
    CSL_MCBSP_CLKPOL_RX_FALLING_EDGE,/* RCV clock Falling Edge */
    1,                              /* Frame-sync pulse width=2 CLKG periods */
    64,                    /* Frame-sync pulse period = 1024 CLKG periods */
    1,                      /* CLKGDIV = 1 means divide by input clock by 2 */
    CSL_MCBSP_SRGCLK_CLKCPU,         /* SCLKME = 0, CLKSM = 1 */                          
    CSL_MCBSP_CLKPOL_SRG_RISING_EDGE, /* CLKS pin signal Rising Edge */           
    CSL_MCBSP_TXFSMODE_DXRCOPY,          /* If FSGM = 1, XMT Frame-sync driven by
                                        sample rate generater, FSG signal */                                                           
    CSL_MCBSP_CLKGSYNCMODE_OFF   /* GSYNC = 0 means no clock synchronisation */             
};                                                                                                     

/*  Multichannel setup  */
CSL_McbspMulChSetup mulChCfg = {
    (CSL_McbspPartMode)CSL_MCBSP_PARTMODE_2PARTITION,      
    (CSL_McbspPartMode)CSL_MCBSP_PARTMODE_2PARTITION,
    (Uint16)0,                     /* Receive multichannel selection enable */
    (Uint16)0,                     /* Transmit multichannel selection enable */
    (CSL_McbspPABlk)CSL_MCBSP_PABLK_0,                    
    (CSL_McbspPBBlk)CSL_MCBSP_PBBLK_1,                     
    (CSL_McbspPABlk)CSL_MCBSP_PABLK_0,                     
    (CSL_McbspPBBlk)CSL_MCBSP_PBBLK_1
           
};                        
                    
/*  Mcbsp hwsetup  */
CSL_McbspHwSetup myHwSetup = {
    &gblCfg,
    &rcvDataCfg,
    &xmtDataCfg,
    &clkCfg,
    &mulChCfg,
    CSL_MCBSP_EMU_FREERUN,
    NULL
};

 /* Initialize the MCBSP CSL module */
    status = CSL_mcbspInit(&pContext);
    
    /* Open the CSL module */
    hMcbsp = CSL_mcbspOpen (&mcbspObj, CSL_MCBSP_0, NULL, &status);


     /* Program MCBSP control registers */
    status = CSL_mcbspHwSetup(hMcbsp, &myHwSetup);

    /* Put SRG, Frame-sync, XMT and RCV in reset */
    ctrlMask =   CSL_MCBSP_CTRL_SRG_DISABLE
               | CSL_MCBSP_CTRL_FSYNC_DISABLE
               | CSL_MCBSP_CTRL_TX_DISABLE
               | CSL_MCBSP_CTRL_RX_DISABLE;
    status = CSL_mcbspHwControl(hMcbsp, CSL_MCBSP_CMD_RESET_CONTROL, &ctrlMask);

    WAIT_FOR_1_CLK;

this is my edma3 configuration:

#define NUMBYTE        40            
#define NUMCHAN        64
#define FRAME_INDEX (-(((NUMCHAN-1)*NUMBYTE)-1))


    C64_enableIER(EDMA_INT_FLAG);//HW INT 4

    /* Module initialization */
    status = CSL_edma3Init(&context);
   
    /* Module level open */
    hModule = CSL_edma3Open(&edmaObj,CSL_EDMA3,NULL,&status);
    
    /* Module setup */
    dmahwSetup.paramNum = 0;
    dmahwSetup.que      = CSL_EDMA3_QUE_0;
    hwSetup.dmaChaSetup = &dmahwSetup;
    hwSetup.qdmaChaSetup = NULL;
    status = CSL_edma3HwSetup(hModule,&hwSetup);
     
     /* --- Setup Transmit Channel (McBSP0 transmit, param 12) --- */
          
    /* Channel open */
    chAttr.regionNum = CSL_EDMA3_REGION_GLOBAL;
    chAttr.chaNum = CSL_EDMA3_CHA_XEVT0;    
    hChannelXmt = CSL_edma3ChannelOpen(&chObj, CSL_EDMA3, &chAttr, &status);
    
    /* Get Param Handle Basic*/
    hParamBasic = CSL_edma3GetParamHandle(hChannelXmt,12,NULL);
    /* Get Param Handle Ping*/
    hParamPing = CSL_edma3GetParamHandle(hChannelXmt,67,NULL);  
    /* Get Param Handle Pong*/          
    hParamPong = CSL_edma3GetParamHandle(hChannelXmt,66,NULL);    
 
    /* Set up parameter block 67 as EDMA transmit ping reload */
    myParamSetup.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, \
                                             CSL_EDMA3_TCCH_DIS, \
                                             CSL_EDMA3_ITCINT_DIS, \
                                             CSL_EDMA3_TCINT_EN, \
                                             CSL_EDMA3_CHA_XEVT0,CSL_EDMA3_TCC_NORMAL,\
                                             CSL_EDMA3_FIFOWIDTH_NONE, \
                                             CSL_EDMA3_STATIC_DIS, \
                                             CSL_EDMA3_SYNC_A, \
                                             CSL_EDMA3_ADDRMODE_INCR, \
                                             CSL_EDMA3_ADDRMODE_INCR );
    myParamSetup.srcAddr = (Uint32)gBufferXmtPing;         
    myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(1,64);       
    myParamSetup.dstAddr = (Uint32)CSL_MCBSP_0_TX_EDMA_REGS;        
    myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(40,0);     
    myParamSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(hParamPong,64);     
    myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(FRAME_INDEX,0);     
    myParamSetup.cCnt = 40;

        /* Set up channel and queue relationships */
    CSL_edma3HwChannelSetupParam(hChannelXmt, 12);
    CSL_edma3HwChannelSetupQue(hChannelXmt, CSL_EDMA3_QUE_1);


    status = CSL_edma3ParamSetup(hParamPing,&myParamSetup);

    /* Set up parameter block 12 as EDMA transmit (start with copy of ping) */
    status = CSL_edma3ParamSetup(hParamBasic,&myParamSetup);
    
    /* Set up parameter block 66 as EDMA transmit pong reload */
    myParamSetup.srcAddr = (Uint32)gBufferXmtPong;
    myParamSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(hParamPing,64);
    status = CSL_edma3ParamSetup(hParamPong,&myParamSetup);
    
    
     /* --- Setup Receive Chan vnel (McBSP0 receive, param 13) --- */

    /* Channel open */
    chAttrRcv.regionNum = CSL_EDMA3_REGION_GLOBAL;
    chAttrRcv.chaNum = CSL_EDMA3_CHA_REVT0;    
    hChannelRcv = CSL_edma3ChannelOpen(&chObjRcv, CSL_EDMA3, &chAttrRcv, &status);


    /* Get Param Handle Basic*/
    hParamBasicRcv = CSL_edma3GetParamHandle(hChannelRcv,13,NULL);
    /* Get Param Handle Ping*/
    hParamPingRcv = CSL_edma3GetParamHandle(hChannelRcv,65,NULL);  
    /* Get Param Handle Pong*/          
    hParamPongRcv = CSL_edma3GetParamHandle(hChannelRcv,64,NULL);


    /* Set up parameter block 65 as EDMA transmit ping reload */
    myParamSetup.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, \
                                             CSL_EDMA3_TCCH_DIS, \
                                             CSL_EDMA3_ITCINT_DIS, \
                                             CSL_EDMA3_TCINT_EN, \
                                             CSL_EDMA3_CHA_REVT0,CSL_EDMA3_TCC_NORMAL,\
                                             CSL_EDMA3_FIFOWIDTH_NONE, \
                                             CSL_EDMA3_STATIC_DIS, \
                                             CSL_EDMA3_SYNC_A, \
                                             CSL_EDMA3_ADDRMODE_INCR, \
                                             CSL_EDMA3_ADDRMODE_INCR );
    myParamSetup.srcAddr = (Uint32)CSL_MCBSP_0_RX_EDMA_REGS;         
    myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(1,64);       
    myParamSetup.dstAddr = (Uint32)gBufferRcvPing;        
    myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(0,40);     
    myParamSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(hParamPongRcv,64);     
    myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0, FRAME_INDEX);     
    myParamSetup.cCnt = 40;

            /* Set up channel and queue relationships */
    CSL_edma3HwChannelSetupParam(hChannelRcv, 13);
    CSL_edma3HwChannelSetupQue(hChannelRcv, CSL_EDMA3_QUE_1);

    status = CSL_edma3ParamSetup(hParamPingRcv,&myParamSetup);

        /* Set up parameter block 13 as EDMA receive (start with copy of ping) */
    status = CSL_edma3ParamSetup(hParamBasicRcv,&myParamSetup);


    /* Set up parameter block 64 as EDMA receive pong reload */
    myParamSetup.dstAddr = (Uint32)gBufferRcvPong;
    myParamSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(hParamPingRcv,64);
    status = CSL_edma3ParamSetup(hParamPongRcv,&myParamSetup);
   
    /* Interrupt enable for the global region interrupts */
    regionIntr.region =  CSL_EDMA3_REGION_GLOBAL  ;   
    regionIntr.intr  =   0x3000 ;   
    regionIntr.intrh  =  0x0000 ;
    CSL_edma3HwControl(hModule,CSL_EDMA3_CMD_INTR_ENABLE,&regionIntr);
 

    /* Transmit event clear and enable */
    CSL_edma3HwChannelControl(hChannelXmt,CSL_EDMA3_CMD_CHANNEL_CLEAR,NULL);
    CSL_edma3HwChannelControl(hChannelXmt,CSL_EDMA3_CMD_CHANNEL_ENABLE,NULL);
    /* Receive event clear and enable */
    CSL_edma3HwChannelControl(hChannelRcv,CSL_EDMA3_CMD_CHANNEL_CLEAR,NULL);
    CSL_edma3HwChannelControl(hChannelRcv,CSL_EDMA3_CMD_CHANNEL_ENABLE,NULL);

    /* Clear CPU interrupt event 24 (EVTCLR0) */
    *((Uint32*)0x1800040) = 0x01000000;

    /* Enable CPU interrupt event 24 (EVTMASK0) */
    *((Uint32*)0x1800080) = 0x01000000;
         
    /* clear the error registers */
    chErrClear.missed = TRUE;
    chErrClear.secEvt = TRUE;
    CSL_edma3HwChannelControl (hChannelXmt, CSL_EDMA3_CMD_CHANNEL_CLEARERR, &chErrClear);
    CSL_edma3HwChannelControl (hChannelRcv, CSL_EDMA3_CMD_CHANNEL_CLEARERR, &chErrClear);
 

    /* Trigger Channel */
    CSL_edma3HwChannelControl(hChannelXmt,CSL_EDMA3_CMD_CHANNEL_SET,NULL);
    CSL_edma3HwChannelControl(hChannelRcv,CSL_EDMA3_CMD_CHANNEL_SET,NULL);

at the end, re-enable int e start mcbsp:

/* Re-enable global interrupts */
    HWI_enable();

    /* Enable MCBSP0 transmit and receive */
    ctrlMask = CSL_MCBSP_CTRL_TX_ENABLE | CSL_MCBSP_CTRL_RX_ENABLE;
    CSL_mcbspHwControl(hMcbsp, CSL_MCBSP_CMD_RESET_CONTROL, &ctrlMask);

this is the routine for EDMA interrupt called by BIOS:

void edmaHwi(void)
{
    Uint32 intr, j;
  static Uint32       pingOrPong = PING;
    static Int16        xmtdone = 0, rcvdone = 0;
    Bool  gpioEn;


    /* Check for pending EDMA event interrupts (IPR) */
    intr = *((Uint32*)0x02a01068);

    if (intr & 0x1000)
    {
        xmtdone = 1;        
    }
    if (intr & 0x2000)
    {
        rcvdone = 1;        
    }
    if (xmtdone && rcvdone)
    {
  
        if (pingOrPong == PING)
        {

            pingOrPong = PONG;
            SWI_or(&processBufferSwi, PING);   
        }
        else
        {
            pingOrPong = PING;
            SWI_or(&processBufferSwi, PONG);
        }
        rcvdone = 0;
        xmtdone = 0;
    }

        /* Clear CPU interrupt event 24 (EVTCLR0) */
    *((Uint32*)0x1800040) = 0x01000000;

 
    /* Clear processed EDMA event interrupts (ICR) */
    *((Uint32*)0x02a01070) = intr;

}

  • Alessandro,

    Welcome to the TI E2E forum. I hope you will find many good answers here and in the TI.com documents and in the TI Wiki Pages. Be sure to search those for helpful information and to browse for the questions others may have asked on similar topics.

    Synchronization of data with FrameSync is usually caused by not following the initialization procedure in the McBSP User Guide. This is listed in Section 7.1 "General Initialization Procedure". Please go through this section line-by-line to make sure you are following the requirements. Pay special attention to number 7, which is what trips up most people.

    There may be a problem with combining the McBSP and EDMA3 initialization procedures.

    Make careful examination of the CHANNEL_SET commands that you use. These may not be necessary, but I am not positive just from looking at the code.

    Regards,
    RandyP