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.

Regarding DMA event trigger in C5505

A little confusion regarding DMA event trigger ..

Does DMA transfer automatically start when the corresponding event occurs??

In my application,I am using DMA transfer to transfer data from a peripheral connected through I2S..So, I have put I2S0_RX as event trigger.

Don't I need to call the function in which dma_start(mydma_handle), dma_config() are all written?

If Yes, then what is the difference between Interrupt(enabled using the same I2S_RX signal) and Event trigger?

Thanks.

  • Hi,

    Not sure I understand your question.

    A DMA transfer does begin when the corresponding event occurs. Its interrupt (if enabled) fires after completing the transfer.

    The I2S event will start the DMA whereas an I2S interrupt will branch the CPU to the I2S ISR... It is recommended to disable CPU datatransfer
    interrupts in the I2SINTMASK register when using the DMA for data transfers.

    The DMA can run in autoreload mode, where it transfers data after the event, then automatically reloads the same configuration and waits for a new event.

    Check out 10.2.11 DMA Event Support and 10.2.14.1 Initialization and Configuration Steps in the I2S chapter of the TRM (http://www.ti.com/lit/ug/spruh87c/spruh87c.pdf).

    Hope this helps,
    Mark

  • Hi Mark,

    Thanks for the attached pdf.

    I have understood it as follows.Please correct me if I am wrong.

    So,in interrupt-enabled mode of DMA, channel sends an interrupt to CPU on completion of the programmed transfer.

    In my project,I need to read data from a peripheral connected through I2S using DMA.I have done it as follows.Please check if I am correct.

    1.Open I2S in interrupt mode. I2S_open(I2S_INSTANCE0, I2S_INTERRUPT, I2S_CHAN_STEREO);

    2.Enable I2S RX interrupt.         IRQ_plug (PROG1_EVENT, &i2s_rxIsr);     IRQ_enable(PROG1_EVENT);

    3.Invoke DMA in I2S ISR. DMA is configured as follows---no event synchronisation and interrupt enabled.Source buffer is I2S0RXLT0.

    4.When DMA transfer is complete, interrupt is generated which executes DMA_ISR().   In DMA_ISR(),I have saved the contents of left and right buffers.After 160 such  transfers(my frame_size is 160), a variable is set.

    I have attached the code for this

    /*  ============================================================================
     *   Copyright (c) Texas Instruments Inc 2002, 2003, 2004, 2005, 2008
     *
     *   Use of this software is controlled by the terms and conditions found in the
     *   license agreement under which this software has been supplied.
     *  ============================================================================
     */
    
    /** @file csl_i2s_DmaExample.c
     *
     *  @brief Test code to verify the CSL I2S functionality in DMA mode
     *
     *
     * \page    page6  I2S EXAMPLE DOCUMENTATION
     *
     * \section I2S2   I2S EXAMPLE2 - DMA MODE TEST
     *
     * \subsection I2S2x    TEST DESCRIPTION:
     *		This test verifies the operation of CSL I2S module in DMA mode.
     * I2S module on C5505/C5515 DSP is used to exchange the audio data between
     * the audio codec and DSP.
     *
     * Testing of the I2S with the audio codec is not possible as codec is not
     * part of the CSL package. This test verifies the I2S operation in loopback
     * mode. In loopback mode of operation data written to the I2S data transmit
     * registers will be transmitted to the I2S data receive registers. CSL DMA
     * module should be configured for the I2S Tx and Rx operations.
     * DMA module is used to transfer the data between CPU memory and I2S data
     * registers. I2S is configured to master mode, stereo, 16bit data length and
     * to loop back mode. Due to word swap behavior of the DMA while transferring
     * the data to/from I2S, I2S write data buffer should be word swapped before
     * transferring it to the I2S registers. In case of I2S no word swap is
     * required on the data received due internal word swap by the I2S in loopback
     * mode. I2S data transfer is enabled and DMA is started using DMA_start() API.
     * DMA writes the data to the I2s Tx registers. After successful completion of
     * write operation DMA is configured for Rx operation and again started to read
     * the data from I2S Rx registers. I2S write and read buffers are compared for
     * the data verification.
     *
     * NOTE: THIS TEST HAS BEEN DEVELOPED TO WORK WITH CHIP VERSIONS C5505 AND
     * C5515. MAKE SURE THAT PROPER CHIP VERSION MACRO IS DEFINED IN THE FILE
     * c55xx_csl\inc\csl_general.h.
     *
     * \subsection I2S2y    TEST PROCEDURE:
     *  @li Open the CCS and connect the target (C5505/C5515 EVM)
     *  @li Open the project "CSL_I2S_DMAExampale_Out.pjt" and build it
     *  @li Load the program on to the target
     *  @li Set the PLL frequency to 12.288MHz
     *  @li Run the program and observe the test result
     *  @li Repeat the test at PLL frequencies 40, 60, 75 and 100MHz
     *  @li Repeat the test in Release mode
     *
     * \subsection I2S2z    TEST RESULT:
     *  @li All the CSL APIs should return success
     *  @li Read and write data buffer comparison should be successful.
     *
     * ============================================================================
     */
    
    /* ============================================================================
     * Revision History
     * ================
     * 05-Sep-2008 Created
     * ============================================================================
     */
    
    #include "csl_dma.h"
    #include "csl_i2s.h"
    #include <csl_general.h>
    #include <stdio.h>
    #include "usbstk5505_i2s.h"
    
    #define CSL_TEST_FAILED         (1)
    #define CSL_TEST_PASSED         (0)
    #define CSL_DMA0_CH0            (0)
    #define CSL_I2S_DMA_BUF_LEN		(1) //C changed from 1 to 160
    #define FRAME_SIZE  (160)
    
    //start... from intc example
    #include "csl_intc.h"
    static int count ;
    static int isrEntryCount = 0;
    
    //#define CSL_DMA_BUFFER_SIZE 1024
    
    /* Reference the start of the interrupt vector table */
    extern void VECSTART(void);
    /* Protype declaration for ISR function */
    interrupt void dma_isr(void);
    
    /* Declaration of the buffer */
    //Uint16 dmaSRCBuff[CSL_DMA_BUFFER_SIZE];
    //Uint16 dmaDESTBuff[CSL_DMA_BUFFER_SIZE];
    CSL_DMA_Handle 		dmaHandle;
    CSL_DMA_Config 		dmaConfig;
    CSL_DMA_Config 		getdmaConfig;
    //end... from intc example
    
    
    
    
    //extern Int16  USBSTK5505_I2S_readLeft();
    //extern Int16  USBSTK5505_I2S_readRight();
    
    CSL_DMA_ChannelObj dmaObj;
    
    CSL_DMA_Handle dmaLeftTxHandle;
    CSL_DMA_Handle dmaRightTxHandle;
    CSL_DMA_Handle dmaLeftRxHandle;
    CSL_DMA_Handle dmaRightRxHandle;
    CSL_DMA_Config dmaConfig;
    //#pragma DATA_ALIGN(i2sDmaWriteLeftBuff, 8); //C
    Uint32 i2sDmaWriteLeftBuff[CSL_I2S_DMA_BUF_LEN];// = {0xDEADBEEF}; //C
    //#pragma DATA_ALIGN(i2sDmaWriteRightBuff, 8); //C
    Uint32 i2sDmaWriteRightBuff[CSL_I2S_DMA_BUF_LEN];// = {0x12345678}; //C
    //#pragma DATA_ALIGN(i2sDmaReadLeftBuff, 8); //C
    Uint32 i2sDmaReadLeftBuff[CSL_I2S_DMA_BUF_LEN];// = {0x00000000}; //C
    //#pragma DATA_ALIGN(i2sDmaReadRightBuff, 8); //C
    Uint32 i2sDmaReadRightBuff[CSL_I2S_DMA_BUF_LEN];// = {0x00000000}; //C
    
     Uint32 RcvL1[FRAME_SIZE];
     Int16 canEncode;
    Uint32 RcvR1[FRAME_SIZE];
    Int16 LeftBuff=0;
        Int16 RightBuff=0;
        
        
    ioport CSL_I2sRegs	  *regs;
    CSL_I2sHandle	hI2s;
    Int16 status = CSL_TEST_FAILED;
    Int16 result;
    	
    	
    //extern Int16 aic3204_codec_readLeft();
     //extern Int16 aic3204_codec_readRight();
     CSL_DMA_Handle CSL_configDmaForI2s(CSL_DMAChanNum    chanNum)
    {
    	CSL_DMA_Handle    dmaHandle;
    	CSL_Status        status;
    	ioport volatile CSL_SysRegs		  *sysRegs;
    
    	sysRegs = (CSL_SysRegs *)CSL_SYSCTRL_REGS;
    
    	/*enable the corresponding DMA clock from PCGCR Registers*/
        CSL_FINS(sysRegs->PCGCR1, SYS_PCGCR1_DMA0CG, CSL_SYS_PCGCR1_DMA0CG_ACTIVE);
    	CSL_FINS(sysRegs->PCGCR2, SYS_PCGCR2_DMA1CG, CSL_SYS_PCGCR2_DMA1CG_ACTIVE);
    	CSL_FINS(sysRegs->PCGCR2, SYS_PCGCR2_DMA2CG, CSL_SYS_PCGCR2_DMA2CG_ACTIVE);
    	CSL_FINS(sysRegs->PCGCR2, SYS_PCGCR2_DMA3CG, CSL_SYS_PCGCR2_DMA3CG_ACTIVE);
    
        status = DMA_init();
        if (status != CSL_SOK)
        {
            printf("DMA_init() Failed \n");
           // dmaHandle = NULL;
        }
    
    	dmaHandle = DMA_open(chanNum, &dmaObj,&status);
        if (dmaHandle == NULL)
        {
            printf("DMA_open() Failed \n");
           // dmaHandle = NULL;
        }
    
    	status = DMA_config(dmaHandle, &dmaConfig);
        if (status != CSL_SOK)
        {
            printf("DMA_config() Failed \n");
           // dmaHandle = NULL;
        }
    
        return(dmaHandle);
    }
     
     
     /*
    	This is ISR for the data Receive.
    	This function returns:
    	Void               -void
    */
    interrupt void i2s_txIsr()
    {
    	Int16 			result;
    
    	IRQ_disable(PROG0_EVENT);
    
    	/** Write the buffer data to the registers					*/
    	//result = I2S_write(i2sHandle, i2sIntcWriteBuff, CSL_I2S_BUF_LEN);
    	
    }
    /*
    	This is ISR for the data transmission.
    	This function returns:
    	Void               -void
    */
    interrupt void i2s_rxIsr()
    {
    	Int16 			result;
    
    	IRQ_disable(PROG1_EVENT);
    	/** Read data from register and buffered					*/
    	//result = I2S_read(i2sHandle, i2sIntcReadBuff, CSL_I2S_BUF_LEN);
    	
    	
    		/* Configure DMA channel  for I2S read left */
        	
        	
        #if (defined(CHIP_C5505_C5515) || defined(CHIP_C5504_C5514))
        	dmaConfig.pingPongMode = CSL_DMA_PING_PONG_DISABLE;
        #endif
        
        	dmaConfig.autoMode     = CSL_DMA_AUTORELOAD_DISABLE;
        	dmaConfig.burstLen     = CSL_DMA_TXBURST_8WORD;
        	dmaConfig.trigger      = CSL_DMA_SOFTWARE_TRIGGER;
        	dmaConfig.dmaEvt       = CSL_DMA_EVT_NONE;
        	dmaConfig.dmaInt       = CSL_DMA_INTERRUPT_ENABLE;
        	dmaConfig.chanDir      = CSL_DMA_READ;
        	dmaConfig.trfType      = CSL_DMA_TRANSFER_IO_MEMORY;
        	dmaConfig.dataLen      = 1;
        	//dmaConfig.srcAddr      = USBSTK5505_I2S_readLeft();
        	dmaConfig.srcAddr      = regs->I2SRXLT0;
        	dmaConfig.destAddr     = (Uint16)LeftBuff;
        	dmaLeftRxHandle = CSL_configDmaForI2s(CSL_DMA_CHAN0);
        	if(dmaLeftRxHandle == NULL)
        	{
        		printf("DMA Config for I2S Write Failed!\n!");
        		//return(CSL_TEST_FAILED);
        	}
        
        	I2S_transEnable(hI2s, TRUE);
       	IRQ_setVecs((Uint32)&VECSTART);
    	IRQ_clear(DMA_EVENT);
    
    	IRQ_plug (DMA_EVENT, &dma_isr);
    
    	IRQ_enable(DMA_EVENT);
    	IRQ_globalEnable();
    	
        	status = DMA_start(dmaLeftRxHandle);
        	if(status != CSL_SOK)
        	{
        		printf("I2S Dma Write Failed!!\n");
        		//return(result);
        	}
        	while(DMA_getStatus(dmaLeftRxHandle));
        
        	
        
        
        
        /* Configure DMA channel  for I2S read Right */
        #if (defined(CHIP_C5505_C5515) || defined(CHIP_C5504_C5514))
        	dmaConfig.pingPongMode = CSL_DMA_PING_PONG_DISABLE;
        #endif
      		dmaConfig.autoMode     = CSL_DMA_AUTORELOAD_DISABLE;
        	dmaConfig.burstLen     = CSL_DMA_TXBURST_8WORD;
        	dmaConfig.trigger      = CSL_DMA_SOFTWARE_TRIGGER;
        	dmaConfig.dmaEvt       = CSL_DMA_EVT_NONE;
        	dmaConfig.dmaInt       = CSL_DMA_INTERRUPT_ENABLE;
        	dmaConfig.chanDir      = CSL_DMA_READ;
        	dmaConfig.trfType      = CSL_DMA_TRANSFER_IO_MEMORY;
        	dmaConfig.dataLen      = 1;
        	dmaConfig.srcAddr      = regs->I2SRXRT0;
        	dmaConfig.destAddr     = (Uint16) RightBuff;
        	dmaRightRxHandle = CSL_configDmaForI2s(CSL_DMA_CHAN0);
        	if(dmaRightRxHandle == NULL)
        	{
        		printf("DMA Config for I2S Write Failed!\n!");
        		//return(CSL_TEST_FAILED);
        	}
        
        	I2S_transEnable(hI2s, TRUE);
        	
       	IRQ_setVecs((Uint32)&VECSTART);
    	IRQ_clear(DMA_EVENT);
    
    	IRQ_plug (DMA_EVENT, &dma_isr);
    
    	IRQ_enable(DMA_EVENT);
    	IRQ_globalEnable();
    	
       		status = DMA_start(dmaRightRxHandle);
        	if(status != CSL_SOK)
        	{
        		printf("I2S Dma Write Failed!!\n");
        		//return(result);
        	}
        	while(DMA_getStatus(dmaRightRxHandle));
    	
    }
    
     
     
     
    /*
    	This is functionality is to configure DMA
    	for the source and destination address.
    
    	Function returns:
    	CSL_DMA_Handle              - Valid handler
    	NULL                        - Invalid handler
    */
    
    
    /*
    	This is functionality Transmit  and
    	receive data with DMA mode.
    	The data transmission and receive happen in stereo mode.
    
    	Function returns:
    	CSL_TEST_FAILED                -Failure
    	CSL_TEST_PASSED                -Success
    */
    void i2s_DMA_sample(void)
    {
    	
    	
    	I2S_Config		hwConfig;
    	//Uint16 			looper;
        
        //Int16 no_of_dmacalls;
        
        
        
        
     
    	/*for(looper=0; looper < CSL_I2S_DMA_BUF_LEN; looper++)
    	{
    		//i2sDmaWriteLeftBuff[looper] = 0x12345678;//which is to be written 
    		LeftBuff[looper]	= 0;
            RightBuff[looper]	= 0;
    	}*/
    
    	/* On C5505/C5515 DSP DMA swaps the words in the source buffer
    	   before transferring it to the I2S registers. No data mismatch is
    	   observed When the  write and read operations are done in DMA mode
    	   as the word swap occurs in both the operations.
    	   There will be data mismatch if data write is in DMA mode
    	   and read is in polling mode or vice versa.
    	   To ensure that the data will be written to memory properly in DMA mode
    	   words in the write buffer are swapped by software. During DMA transfer
    	   DMA hardware again will do a word swap which will bring the data buffer
    	   back to original values. Word swap is not required for read
    	   buffer after read operation in DMA mode as I2S hardware will do
    	   a word swap on the data before looping it back to receive registers.
    	   This is peculiar behavior of the I2S HW in loopback mode
    	 */
    	/* Swap words in I2S write buffer */
    	result = DMA_swapWords((Uint16*)i2sDmaWriteLeftBuff, 2*CSL_I2S_DMA_BUF_LEN);
    	if(result != CSL_SOK)
    	{
    		printf ("DMA word swap API failed\n");
    		status = CSL_TEST_FAILED;
    		//return (status);
    	}
    
    	/** Open the device with instance 0							*/
    	hI2s = I2S_open(I2S_INSTANCE0, I2S_INTERRUPT, I2S_CHAN_STEREO);
    	if(NULL == hI2s)
    	{
    		status = CSL_TEST_FAILED;
    		//return (status);
    	}
    	else
    	{
    		printf ("I2S Module Instance opened successfully\n");
    	}
    
    	/** Set the value for the configure structure				*/
    	hwConfig.dataType 			= I2S_STEREO_ENABLE;
    	hwConfig.loopBackMode 		= I2S_LOOPBACK_ENABLE;
    	hwConfig.fsPol 				= I2S_FSPOL_LOW;
    	hwConfig.clkPol				= I2S_FALLING_EDGE;
    	hwConfig.datadelay			= I2S_DATADELAY_ONEBIT;
    	hwConfig.datapack			= I2S_DATAPACK_ENABLE;
    	hwConfig.signext			= I2S_SIGNEXT_DISABLE;
    	hwConfig.wordLen			= I2S_WORDLEN_16;
    	hwConfig.i2sMode			= I2S_MASTER;
    	hwConfig.clkDiv				= I2S_CLKDIV4;
    	hwConfig.fsDiv				= I2S_FSDIV32;
    	hwConfig.FError				= I2S_FSERROR_DISABLE;
    	hwConfig.OuError			= I2S_OUERROR_DISABLE;
    
    	/** Configure hardware registers							*/
    	result = I2S_setup(hI2s, &hwConfig);
    	if(result != CSL_SOK)
    	{
    		status = CSL_TEST_FAILED;
    		//return (status);
    	}
    	else
    	{
    		printf ("I2S Module Configured successfully\n");
    	}
         
         regs = hI2s->hwRegs;
         
        
        IRQ_globalDisable();
    	IRQ_clearAll();
    	IRQ_disableAll();
    
    	IRQ_setVecs((Uint32)&VECSTART);
    	IRQ_clear(PROG1_EVENT);  //CSL_DMA_EVT_I2S0_RX
    
    	IRQ_plug (PROG1_EVENT, &i2s_rxIsr);
    
    	IRQ_enable(PROG1_EVENT);
    	IRQ_globalEnable();
    	
    	
        
            	
    }
    //if(no_of_dmacalls==FRAME_SIZE)
    //{
      // canEncode=1;
    //}
    
    
    interrupt void dma_isr(void)
    {
        int ifrValue;
    
      	ifrValue = CSL_SYSCTRL_REGS->DMAIFR;
    	CSL_SYSCTRL_REGS->DMAIFR |= ifrValue;
    
    	++count;
    	++isrEntryCount;
    	
    	RcvL1[isrEntryCount]=LeftBuff;
        RcvR1[isrEntryCount]=RightBuff;
        if(isrEntryCount==160)//implies one frame of data is ready
        {
        canEncode=1;
        }
    }
    
    
    

    , which is a modified version of csl_i2s_intcExample.c and csl_i2s_DmaExample.c .

    Please go through if possible and check if I am wrong anywhere.Else, please check the algorithm mentioned above.

  • Hi

    The above program is getting compiled but there is a linking error.

    Error:

    "C:\\Program Files (x86)\\Texas
    Instruments\\ccsv4\\emulation\\boards\\usbstk5505_v2\\c55xx_csl\\ccs_v4.0_ex
    amples\\cslVC5505\\Debug\\cslVC5505.lib<vectors.obj>" has a Tag_Memory_Model
    attribute value of "2" that is different than one previously seen ("1");
    combining incompatible files

    As I mentioned earlier, a variable is set after 160 such transfers.

    In the main program, while(variable)

    {

    //encoding of that data using speex

    }

    I guess speex uses a different memory model as compared to usbstk (cslVC5505.lib).

    can anyone suggest a way to change the memory models of inbuilt  libraries?

  • Hi

    I get a new error when I change the memory model of cslVC5505.lib to SMALL.

    Error:

    file "C:\\Program Files (x86)\\Texas
    Instruments\\ccsv4\\emulation\\boards\\usbstk5505_v2\\c55xx_csl\\ccs_v4.0_ex
    amples\\cslVC5505\\Debug\\cslVC5505.lib<vectors.obj>" specifies "C55x CPU
    Rev 3.x", which is not compatible with "C55x CPU Rev 2.x" specified in a
    previous file or on the command line

    I could not find where it was defined as C55x CPU Rev 2.x.Can anyone help?