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.

Edma3-event triggered

Hi all,

I am using C6748 for a university project.

I am trying to use activate the edma3 to transfer samples from the Edma to Left and right ping pong buffers.

Here are the steps I took:

1. configure Mcasp without starting it.

2. Edma3: requesting 3 channels: 1. active 2. linking channel -for ping buffer and 3. linking channel for pong

3. setting the channels parameters using 2 Pset's one for ping and one for pong.

4. enabling the transfer

5. starting Mcasp

It don't receive any response from the Edma, it seems that it does not start at all!

I attached two of my configuration files-

Is there something wrong with my configuration/procedure?

thanks in advance!

Ariel

EDMA3_DRV_PaRAMRegs ParamSetRcvPing = {0,0,0,0,0,0,0,0,0,0,0,0};
EDMA3_DRV_PaRAMRegs ParamSetRcvPong = {0,0,0,0,0,0,0,0,0,0,0,0};

unsigned int EdmaActiveRcvChannelId,EdmaLinkRcvChannelIdPing,EdmaLinkRcvChannelIdPong;

unsigned int EdmaTccPing=0,EdmaTccPingLink=0,EdmaTccPongLink = 0;

dstBuffping = (signed char*)_dstBuffping;
dstBuffpong = (signed char*)_dstBuffpong;

/***********************************************************************************
* step 1: request 3  channels:
* 1. 1 Active channel  
* 2. two linking channels  for ping & pong buffers
* *********************************************************************************/
	
    /* Setup for Channel 1*/
    	EdmaTccPing = EDMA3_DRV_TCC_ANY;
    	EdmaTccPingLink = EDMA3_DRV_TCC_ANY;
    	EdmaTccPongLink = EDMA3_DRV_TCC_ANY;
    
    	EdmaActiveRcvChannelId = EDMA3_DRV_HW_CHANNEL_EVENT_0; //McAsp receive 
    	EdmaLinkRcvChannelIdPing = EDMA3_DRV_LINK_CHANNEL;
    	EdmaLinkRcvChannelIdPong = EDMA3_DRV_LINK_CHANNEL;
    	
	
    /* 3 Receive channels */
    if (result == EDMA3_DRV_SOK)
    {
        result = EDMA3_DRV_requestChannel (hEdma, &EdmaActiveRcvChannelId, &EdmaTccPing,(EDMA3_RM_EventQueue)0,                                        
                                            &callback1, NULL);
    }

	if (result == EDMA3_DRV_SOK)
    {
		result = EDMA3_DRV_requestChannel( hEdma, &EdmaLinkRcvChannelIdPing, 
					&EdmaTccPingLink, (EDMA3_RM_EventQueue)0, &callback1, NULL );
    }		
	if (result == EDMA3_DRV_SOK)
    {
		result = EDMA3_DRV_requestChannel( hEdma, &EdmaLinkRcvChannelIdPong, 
					&EdmaTccPongLink, (EDMA3_RM_EventQueue)1, &callback1, NULL );
    }


/***********************************************************************************
* step 2: configure paramsets for the 3 channels:
* The active  channel and the ping channel have the same param sets.
* The pong channel has a different destination address
**********************************************************************************/
	 
	 /* set parameters for the 3 receive channels */
	    
        /* Fill the PaRAM Set with transfer specific information */
        ParamSetRcvPing.srcAddr    = (unsigned int)(&MCASP->XBUF12);
        ParamSetRcvPong.srcAddr    = (unsigned int)(&MCASP->XBUF12);
        ParamSetRcvPing.destAddr   = (unsigned int)(dstBuffping);
        //change destination address
        ParamSetRcvPong.destAddr   = (unsigned int)(dstBuffpong);

        /* Bidx/Cidx - between -32767 and 32767*/        
        ParamSetRcvPing.srcBIdx    = 0;
        ParamSetRcvPong.srcBIdx    = 0;
        ParamSetRcvPing.destBIdx   = 2048;
        ParamSetRcvPong.destBIdx   = 2048;
        ParamSetRcvPing.srcCIdx    = 0;
	ParamSetRcvPong.srcCIdx    = 0;
	ParamSetRcvPing.destCIdx   = -2046;
	ParamSetRcvPong.destCIdx   = -2046;
        
        /* ACnt/BCnt/CCnt- between 0 and 65535 */
        
        ParamSetRcvPing.aCnt       = acnt;
        ParamSetRcvPong.aCnt       = acnt;
        ParamSetRcvPing.bCnt       = bcnt;
        ParamSetRcvPong.bCnt       = bcnt;
        ParamSetRcvPing.cCnt       = ccnt;
        ParamSetRcvPong.cCnt       = ccnt;

        /* For AB-synchronized transfers, BCNTRLD is not used. */
        ParamSetRcvPing.bCntReload = BRCnt;
        ParamSetRcvPong.bCntReload = BRCnt;

        ParamSetRcvPing.linkAddr   = 0xFFFFu;
        ParamSetRcvPong.linkAddr   = 0xFFFFu;

        /* Src & Dest are in INCR modes */
        ParamSetRcvPing.opt &= 0xFFFFFFFCu;
        ParamSetRcvPong.opt &= 0xFFFFFFFCu;
        /* Program the TCC */
        ParamSetRcvPing.opt |= ((EdmaTccPing << OPT_TCC_SHIFT) & OPT_TCC_MASK);
        ParamSetRcvPong.opt |= ((EdmaTccPongLink << OPT_TCC_SHIFT) & OPT_TCC_MASK);

        /* Enable  Final transfer completion interrupt */
        //ParamSetRcvPing.opt |= (1 << OPT_ITCINTEN_SHIFT);
        ParamSetRcvPing.opt |= (1 << OPT_TCINTEN_SHIFT);
        ParamSetRcvPong.opt |= (1 << OPT_TCINTEN_SHIFT);
        
        ParamSetRcvPing.opt &= 0xFFFFFFFBu;
        ParamSetRcvPong.opt &= 0xFFFFFFFBu;
       

        /* Now, write the PaRAM Set. */
        if (result == EDMA3_DRV_SOK)
        {
        	result = EDMA3_DRV_setPaRAM(hEdma, EdmaActiveRcvChannelId, &ParamSetRcvPing);
        }

        if (result == EDMA3_DRV_SOK)
        {
        	result = EDMA3_DRV_setPaRAM(hEdma, EdmaLinkRcvChannelIdPing, &ParamSetRcvPing);
        }
        
        if (result == EDMA3_DRV_SOK)
        {
        	        	 
        	result = EDMA3_DRV_setPaRAM(hEdma, EdmaLinkRcvChannelIdPong, &ParamSetRcvPong);
        }

/***********************************************************************************
 * step 3: link channels
 * The active channel should be linked to the pong channel
 * The pong channel should be linked to the ping channel
 **********************************************************************************/

    if (result == EDMA3_DRV_SOK)
    {
		result = EDMA3_DRV_linkChannel( hEdma,
							EdmaActiveRcvChannelId,
							EdmaLinkRcvChannelIdPong );  
    }
    if (result == EDMA3_DRV_SOK)
    {
 		result = EDMA3_DRV_linkChannel( hEdma,
							EdmaLinkRcvChannelIdPong,
							EdmaLinkRcvChannelIdPing );  
    }

if (result == EDMA3_DRV_SOK)
    {
	 	result = EDMA3_DRV_enableTransfer (hEdma, EdmaActiveRcvChannelId,
                                                EDMA3_DRV_TRIG_MODE_EVENT);
    }
	 
    McASP_Start_TTO();							// start McASP clocks	   
/__key/CommunityServer-Discussions-Components-Files/112/5126.ConfigureMcAsp.txt] 

  • //-----------------------------------------------------------------------------
    // Title:   Technical Training Organization (TTO) BIOS Workshop 5.50
    // File:	mcasp_TTO.c 
    // Rev:		1.0
    // Date:	08-31-2010
    // Author:	Eric Wilbur (ericw@ti.com)
    // Ref:		C6748 BSL, Experimenter Test Example (audio, mcasp)
    //
    // Brief:	Init McASP clocks/control & interrupts, dummy writes to XDATA
    //
    // Notes:	1. Refer to main.h for key definitions
    //			2. Underrun is a SERIOUS condition on the McASP. Notice that
    //             dummy writes occur at selected points to keep XDATA filled
    //			3. For symbol definitions, refer to evmc6748_mcasp.h
    //			
    //-----------------------------------------------------------------------------
    
    //-----------------------------------------------------------------------------
    // Includes
    //-----------------------------------------------------------------------------
    #include "main.h"
    
    //-----------------------------------------------------------------------------
    // DEFINES (enable XDATA/RDATA interrupts in McASP)
    //-----------------------------------------------------------------------------
    #define RDATA 0x20 							// R/XDATA interrupt mask
    #define XDATA 0x20
    
    //-----------------------------------------------------------------------------
    // Private Defines and Macros
    //-----------------------------------------------------------------------------
    // pinmux defines.
    #define PINMUX_MCASP_REG_0       (0)
    #define PINMUX_MCASP_MASK_0      (0x00FFFFFF)
    #define PINMUX_MCASP_VAL_0       (0x00111111)
    #define PINMUX_MCASP_REG_1       (1)
    #define PINMUX_MCASP_MASK_1      (0x000FF000)
    #define PINMUX_MCASP_VAL_1       (0x00011000)
    
    
    //-----------------------------------------------------------------------------
    // McASP_Init_TTO()
    //-----------------------------------------------------------------------------
    
    void McASP_Init_TTO(void)
    {
       // enable the psc and config pinmux for mcasp.
       EVMC6748_lpscTransition(PSC1, DOMAIN0, LPSC_MCASP0, PSC_ENABLE);
       EVMC6748_pinmuxConfig(PINMUX_MCASP_REG_0, PINMUX_MCASP_MASK_0, PINMUX_MCASP_VAL_0);
       EVMC6748_pinmuxConfig(PINMUX_MCASP_REG_1, PINMUX_MCASP_MASK_1, PINMUX_MCASP_VAL_1);
       
       // reset mcasp.
       MCASP->GBLCTL  = 0;
    
       // NOTE: ROR 16-bits enabled for both XMT/RCV. SLOT SIZE = 16 bits, 1-bit delay
       //       MCLK = 2.456MHz, CLKRDIV = 16, SO, bitclk = MCLK/CLKRDIV = 1.536MHz
       //       SAMPLE RATE = 1.536MHz/32bits = 48KHz
    
       // configure receive registers for I2S
       MCASP->RMASK      = 0xFFFFFFFF;		// all 32-bits NOT masked
       MCASP->RFMT       = 0x0001807C;		// MSB first, align left, slot=16bits, 1-bit delay, ROR 16-bits
       MCASP->AFSRCTL    = 0x00000112;		// int'l gen'd, FS/word, 2 SLOT TDM = I2S
       MCASP->ACLKRCTL   = 0x000000AF;		// rising edge, clkrm internal, /16 CLKRDIV
       MCASP->AHCLKRCTL  = 0x00000000;		// HCLKRDIV = 1
       MCASP->RTDM       = 0x00000003;		// SLOT 0 & 1 active I2S
       MCASP->RINTCTL    = 0x00000000;		// ints disabled (enabled later though)
       MCASP->RCLKCHK    = 0x00FF0008;		// RMAX = FF, RPS = /256
    
       // configure transmit registers for I2S - all same as above
       MCASP->XMASK      = 0xFFFFFFFF;
       MCASP->XFMT       = 0x0001807C;		 
       MCASP->AFSXCTL    = 0x00000112;
       MCASP->ACLKXCTL   = 0x000000AF;
       MCASP->AHCLKXCTL  = 0x00000000;
       MCASP->XTDM       = 0x00000003;
       MCASP->XINTCTL    = 0x00000000;
       MCASP->XCLKCHK    = 0x00FF0008;
    
       // config serializers (11 = xmit, 12 = rcv)
       MCASP->SRCTL11    = 0x000D;					// XMT
       MCASP->SRCTL12    = 0x000E;					// RCV
    
       // config pin function and direction.
       MCASP->PFUNC      = 0;
       MCASP->PDIR       = 0x14000800;
    
       MCASP->DITCTL     = 0x00000000;
       MCASP->DLBCTL     = 0x00000000;
       MCASP->AMUTE      = 0x00000000;
    
    }
    
    //-----------------------------------------------------------------------------
    // McASP_Start_TTO()
    //-----------------------------------------------------------------------------
    
    void McASP_Start_TTO(void)
    {
    
       // enable the audio clocks, verifying each bit is properly set.
    	SETBIT(MCASP->XGBLCTL, XHCLKRST);
        while (!CHKBIT(MCASP->XGBLCTL, XHCLKRST)) {}
        SETBIT(MCASP->RGBLCTL, RHCLKRST);
        while (!CHKBIT(MCASP->RGBLCTL, RHCLKRST)) {}
    
        SETBIT(MCASP->XGBLCTL, XCLKRST);
        while (!CHKBIT(MCASP->XGBLCTL, XCLKRST)) {}
        SETBIT(MCASP->RGBLCTL, RCLKRST);
        while (!CHKBIT(MCASP->RGBLCTL, RCLKRST)) {}
    
       	SETBIT(MCASP->RINTCTL, RDATA);					// enable McASP XMT/RCV interrupts
       	while (!CHKBIT(MCASP->RINTCTL, RDATA)) {}		// see #defines at top of file
       	SETBIT(MCASP->XINTCTL, XDATA);
      	while (!CHKBIT(MCASP->XINTCTL, XDATA)) {}
    
        MCASP->XSTAT = 0x0000FFFF;        // Clear all (see procedure in UG)
        MCASP->RSTAT = 0x0000FFFF;        // Clear all
    
    
       SETBIT(MCASP->XGBLCTL, XSRCLR);
       while (!CHKBIT(MCASP->XGBLCTL, XSRCLR)) {}
       SETBIT(MCASP->RGBLCTL, RSRCLR);
       while (!CHKBIT(MCASP->RGBLCTL, RSRCLR)) {}
    
       /* Write a 0, so that no underrun occurs after releasing the state machine */
       MCASP->XBUF11 = 0;
    
       SETBIT(MCASP->XGBLCTL, XSMRST);
       while (!CHKBIT(MCASP->XGBLCTL, XSMRST)) {}
       SETBIT(MCASP->RGBLCTL, RSMRST);
       while (!CHKBIT(MCASP->RGBLCTL, RSMRST)) {}
    
       SETBIT(MCASP->XGBLCTL, XFRST);
       while (!CHKBIT(MCASP->XGBLCTL, XFRST)) {}
       SETBIT(MCASP->RGBLCTL, RFRST);
       while (!CHKBIT(MCASP->RGBLCTL, RFRST)) {}
    
       // wait for transmit ready and send a dummy byte.
       //while(!CHKBIT(MCASP->SRCTL11, XRDY)) {}
       //MCASP->XBUF11 = 0;
       
    }
    
    
    

  • ariel,

    How does your procedure compare to the procedure described in the McASP User's Guide for the C6748?

    Regards,
    RandyP

  • Hi Randy! Thanks for the reply, I found my first problem (a silly mistake- I did only two link operations- the active channel to the first link channel and the first link to the second, but I didn't link the second link channel back to the first), now I have another probelm. As I wrote, I am trying to implement a simple IPO chain, using a ping-pong buffer on the C6748 processor. I created the ping pong buffer using three dma channels (one is the first active and the other two are link channels) The same goes for the output- 3 channels from the output buffers to the output McAsp register. As long as I run a simple loop-back everything works fine. I am trying to implement a simple filter between the input buffer and the output buffer using TI's DSP library. I configured the program as follows: 1. I enabled interrupts for the 3 receive channles: (not intermediate interrupt)- so after a buffer is full (for example the ping buffer) I have a hardware interrupt. I use a callback function for the target of the interrupt. (one of the parameters of the RequestChannel function) 2. In the callback function I post a SWI 3. In the software interrupt I activate the filter on the ping buffer- the output of the filter goes to the output buffer 4. The 3 'transmit channels' (from the output buffers to the McAsp output register) are configured without interrupts It seems that the SW interrupts interfere with the activity of the DMA channels- because once the SWI are activated the input buffers are not updated. Is this a correct way of doing things? Is there an example of an IPO chain using EDMA3? Thanks for the help! Ariel
  • ariel,

    Your system description sounds like a perfect example of an IPO system. All you need to do now is figure out what is wrong with your well-designed implementation.

    The most common problem that could lead to the symptom you describe is cache coherency. As soon as the DSP code reads an external buffer (input data loaded by the EDMA from the McASP), that data is stored in the L1D and/or L2 cache areas. In the CCS memory window, this will show up with a highlighted color. If you click the L1D or L2 check boxes on the Memory view, you will see other data which is what is actually in the external memory.

    Anytime the DMA has loaded a new set of data in the external buffer, the DSP code must use cache coherency commands to invalidate the existing cache before starting to read that new buffer's contents. In the Training section of TI.com, there is a training video set for the C6474 which uses three (3) of the C64x+ cores. It may be helpful for you to review several of the modules. But in particular, the Memory and Cache Module will apply to handling the cache coherency issues. You can find the complete video set at http://focus.ti.com/docs/training/catalog/events/event.jhtml?sku=OLT110002 .

    If this is not the issue, either because you are already handling the cache concerns or because your buffers are in internal DSP memory, then there will be several steps you will want to take to debug the problem. My suggestion in that case is to reduce the SWI to a simple loopback and check if it still fails.

    Regards,
    RandyP

     

    If you need more help, please reply back. If this answers the question, please click  Verify Answer  , below.

  • Hi Randy,

    I just started working again on my project, and your response was a huge help!

    The video section is very informative. I used cache_invalidate after filling the ping/pong buffer (after the input, before the processing)

    and it solved the problem.

    I also noticed that there is an option of canclling cahce all together for a chosen buffer.

    Thanks!!

    Ariel

  • Ariel,

    If you would, please, click the  Verify Answer  button on whichever post(s) represent answers to your question. This will help later readers when searching for answers.

    Cancelling cache by turning off a MAR bit has the effect of disabling cache for a very large region of memory, like 16MB. Depending on the exact nature of your accesses, having cache enabled and then using the cache coherency commands can be the most efficient method. There are only a few cases where disabling cache is better. It is very dependent on the exact algorithm.

    Best of luck with your project.

    Regards,
    RandyP