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.

I2S OUERR and FERR bits set in I2SINTFL does not generate an interrupt

I'm using the C5515A and I don't get any i2s interrupts for overrrun errors or frame sync errors.

The external master i2s device is continually transmitting data.

Interrupts are enabled in the processor and I've verified the IER0.IE15=1  (RCV2 interrupt) and I never see the IFR0.IE15 ever get set.

The debugger register view shows the I2SINTFL.OUERR bit is set.

The description of the I2SINTFL register shows that all the bits in this register are cleared on read.

Does the debugger poll the I2SINTFL in the background, which may cause the bits to get cleared and prevent the isr from being called?

If so, is there a way of disabling 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_gpio.h"
#include "csl_dma.h"
#include "csl_i2s.h"
#include "csl_intc.h" // DJH added for CSL interrupt interface
#include <csl_general.h>
#include <stdio.h>


/* Reference the start of the interrupt vector table */
extern void VECSTART(void);

#ifdef ALGEBRAIC
#define HAL_XF_LED_ON    asm("\tBIT (ST1,#ST1_XF) = #1   ;====> C SOURCE INLINE ASSEMBLY");
#define HAL_XF_LED_OFF   asm("\tBIT (ST1,#ST1_XF) = #0   ;====> C SOURCE INLINE ASSEMBLY");

#else // ALGEBRAIC
#define HAL_XF_LED_ON    asm("\tbset XF;====> C SOURCE INLINE ASSEMBLY")
#define HAL_XF_LED_OFF   asm("\tbclr XF;====> C SOURCE INLINE ASSEMBLY") 
#endif // ALGEBRAIC

// LEDs control for the C5515 EzDSP board v2
                                  // bank DS  GPIO[] 
#define LEDBANK0_LED0_MASK 0x4000 // 0     5   14
#define LEDBANK0_LED1_MASK 0x8000 // 0     6   15
#define LEDBANK1_LED2_MASK 0x0001 // 1     7   16
#define LEDBANK1_LED3_MASK 0x0002 // 1     8   17

#define LEDBANK0_LEDOFF(__mask) (CSL_GPIO_REGS->IOOUTDATA1 |= __mask)
#define LEDBANK0_LEDON(__mask)  (CSL_GPIO_REGS->IOOUTDATA1 &= ~(__mask))
#define LEDBANK1_LEDOFF(__mask) (CSL_GPIO_REGS->IOOUTDATA1 |= __mask)
#define LEDBANK1_LEDON(__mask)  (CSL_GPIO_REGS->IOOUTDATA1 &= ~(__mask))



#define CSL_TEST_FAILED         (1)
#define CSL_TEST_PASSED         (0)
#define CSL_DMA0_CH0            (0)
//#define kDMA_I2S2_PING_DBLWORDS (1)
#define kDMA_I2S2_PING_DBLWORDS (2) // we expect 2 double words to be shifted in (2 words left + 2 words right)
#define CSL_I2S_DMA_BUF_LEN		(kDMA_I2S2_PING_DBLWORDS*2)     // (1) DJH 1 was Default value for demo. changed to 2 for both ping and pong

CSL_DMA_ChannelObj dmaObj;

static CSL_DMA_Handle dmaLeftTxHandle;
static CSL_DMA_Handle dmaRightTxHandle;
static CSL_DMA_Handle dmaLeftRxHandle;
static CSL_DMA_Handle dmaRightRxHandle;
static CSL_DMA_Config dmaConfig;
#pragma DATA_ALIGN(i2sDmaWriteLeftBuff, 8); // 8 to Align to 64 bit boundary. Why not align to a 32 bit boundary???
Uint32 i2sDmaWriteLeftBuff[CSL_I2S_DMA_BUF_LEN] = {0xDEADBEEF};
#pragma DATA_ALIGN(i2sDmaWriteRightBuff, 8);
Uint32 i2sDmaWriteRightBuff[CSL_I2S_DMA_BUF_LEN] = {0x12345678};
#pragma DATA_ALIGN(i2sDmaReadLeftBuff, 8);
Uint32 i2sDmaReadLeftBuff[CSL_I2S_DMA_BUF_LEN] = {0x00000000};
#pragma DATA_ALIGN(i2sDmaReadRightBuff, 8);
Uint32 i2sDmaReadRightBuff[CSL_I2S_DMA_BUF_LEN] = {0x00000000};

// DJH added sensor data buffers to hold multiple samples
#define  SENSORDATA_BUFLEN 256
static volatile Uint32 mSensorBufferLeft[SENSORDATA_BUFLEN];
static volatile Uint32 mSensorBufferRight[SENSORDATA_BUFLEN];

#define  SENSORDATA_BUFWORDS 512 // must be a multiple of 4 since we read 4 16 bit registers for every rx interrupt
static volatile Uint16 mSensorIruptBuffer[SENSORDATA_BUFWORDS];


/* Protype declaration for ISR function */
static interrupt void dma_isr(void);
static interrupt void i2s2rx_isr(void);


/*
	This is functionality is to configure DMA
	for the source and destination address.

	Function returns:
	CSL_DMA_Handle              - Valid handler
	NULL                        - Invalid handler
*/

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;

#if 0
    // DJH no need to do this because DMA_Init does this for us
	/*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);
#endif

	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;
    }

    // For i2s2 we want the i/o address to increment so the address to read
    // both the left and right channel i2s data.  
    if (CSL_DMA_CHAN4 == chanNum) {
      CSL_FINS(dmaHandle->dmaRegs->DMACH0TCR2, DMA_DMACH0TCR2_SRCAMODE, CSL_DMA_ADDR_MODE_INCREMENT);        
    }
    return(dmaHandle);
}

static CSL_GpioObj    gpioObj;
static CSL_GpioObj    *hGpio;

Int16
BoardSetup(void) {
    Int16 			status = CSL_TEST_FAILED;
    CSL_GpioConfig    config;
    /* Open GPIO module */
    hGpio = GPIO_open(&gpioObj, &status);
    if((NULL == hGpio) || (CSL_SOK != status))
    {
        printf("GPIO_open failed\n");
        return(CSL_TEST_FAILED);
    }
	else
	{
		printf("GPIO_open Successful\n");
	}
	    /* Configure the GPIO module */
	    // This code assumes the PPMODE is either MODE1 or MODE6 to support GPIO pins
    config.GPIODIRL     = 0xD001;   // ensure bit 14 and 15, DS5 & DS4  LEDs as output
    config.GPIODIRH     = 0x0403; 
    config.GPIOINTENAL  = 0x0000;   // no interrupts or triggers
    config.GPIOINTENAH  = 0x0000;
	config.GPIOINTTRIGL = 0x0000;
	config.GPIOINTTRIGH = 0x0000;

    status = GPIO_config(hGpio, &config);
    if(CSL_SOK != status)
    {
        printf("GPIO_config failed\n");
        return(CSL_TEST_FAILED);
    }
	else
	{
		printf("GPIO_config Successful\n");
	}
	// turn leds off
    LEDBANK0_LEDON(LEDBANK0_LED0_MASK | LEDBANK0_LED1_MASK);
	return status;
}


/*
	This is functionality to receive data via the slave interface
	in stereo, DSP format, and via DMA

	Function returns:
	CSL_TEST_FAILED                -Failure
	CSL_TEST_PASSED                -Success
*/
Int16 i2s_DMA_sampleSlave(void)
{
	Int16 			status = CSL_TEST_FAILED;
	Int16 			result;
	CSL_I2sHandle	hI2s;
	I2S_Config		hwConfig;
	Uint16 			looper;
    int ledState = 0;
    
    
    IRQ_globalDisable();

	IRQ_clearAll();

	IRQ_disableAll();

	IRQ_setVecs((Uint32)&VECSTART);
    // DJH move the DMA_Init here to clear out any residual DMA configuration
    // and we do it before we reenable interrupts
    status = DMA_init();
    if (status != CSL_SOK)
    {
        printf("DMA_init() Failed \n");
    }    
    status = I2S_init(I2S_INSTANCE2);
    if (status != CSL_SOK)
    {
        printf("I2S_init() Failed \n");
    }   
	IRQ_clear(DMA_EVENT);
	IRQ_plug (DMA_EVENT, &dma_isr);
	IRQ_enable(DMA_EVENT);
	
	// configure the i2s2 interrupt handler
	IRQ_clear(RCV2_EVENT);
	IRQ_plug (RCV2_EVENT, &i2s2rx_isr);
	IRQ_enable(RCV2_EVENT);
	
	IRQ_globalEnable();


	/* Initialize data buffers */
	for(looper=0; looper < CSL_I2S_DMA_BUF_LEN; looper++)
	{
		//i2sDmaWriteLeftBuff[looper] = 0x12345678;
		i2sDmaReadLeftBuff[looper]	= 0;
		//i2sDmaWriteRightBuff[looper] = 0x12345678;
		i2sDmaReadRightBuff[looper]	= 0;
	}

	for(looper=0; looper < SENSORDATA_BUFLEN; looper++)
	{
      mSensorBufferRight[looper] = mSensorBufferLeft[looper] = 0;
	}

	/** Open the device with instance 2							*/
	hI2s = I2S_open(I2S_INSTANCE2, DMA_POLLED, 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;
//#if _UNITTEST_I2S_
//    hwConfig.loopBackMode       = I2S_LOOPBACK_ENABLE;
//    hwConfig.i2sMode            = I2S_MASTER;
//#else
    hwConfig.loopBackMode       = I2S_LOOPBACK_DISABLE;
    hwConfig.i2sMode            = I2S_SLAVE;
//#endif // _UNITTEST_I2S_
    hwConfig.fsPol              = I2S_FSPOL_LOW;
    hwConfig.clkPol             = I2S_RISING_EDGE;
    hwConfig.datadelay          = I2S_DATADELAY_ONEBIT; // I2S_DATADELAY_TWOBIT;
    hwConfig.datapack           = I2S_DATAPACK_DISABLE;
    hwConfig.signext            = I2S_SIGNEXT_DISABLE;
    hwConfig.wordLen            = I2S_WORDLEN_32;
    hwConfig.clkDiv             = I2S_CLKDIV4; //The DSP chip ingores this setting when in slave mode.
    hwConfig.fsDiv              = I2S_FSDIV32; //The DSP chip ingores this setting when in slave mode.
    hwConfig.FError             = I2S_FSERROR_ENABLE;
    hwConfig.OuError            = I2S_OUERROR_ENABLE;

	/** 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");
	}
    // Set the DSP Format flag..The i2s driver by default clears this bit
    hI2s->hwRegs->I2SSCTRL |= CSL_I2S_I2SSCTRL_FRMT_MASK;
    
    // Clear the interrupt mask bits since we're using DMA per 1.2.14.1 of SPRUFX4
    // hI2s->hwRegs->I2SINTMASK = (Uint16)CSL_I2S_I2SINTMASK_RESETVAL;

    // Only enable the frame sync error & overrun error 
    hI2s->hwRegs->I2SINTMASK = (Uint16) (CSL_I2S_I2SINTFL_FERRFL_MASK|CSL_I2S_I2SINTFL_OUERRFL_MASK);


	/* Configure DMA channel 4  for I2S2 Read of left channel*/
#if (defined(CHIP_C5505_C5515) || defined(CHIP_C5504_C5514))
	dmaConfig.pingPongMode = CSL_DMA_PING_PONG_ENABLE;
#endif
    //dmaConfig.autoMode     = CSL_DMA_AUTORELOAD_DISABLE;
    dmaConfig.autoMode     = CSL_DMA_AUTORELOAD_ENABLE;
	// dmaConfig.burstLen     = CSL_DMA_TXBURST_1WORD;  // 1x 32 bit transfer for i2s event
	dmaConfig.burstLen     = CSL_DMA_TXBURST_2WORD;  // 2x 32 bit transfer for i2s event
	dmaConfig.trigger      = CSL_DMA_EVENT_TRIGGER;
	dmaConfig.dmaEvt       = CSL_DMA_EVT_I2S2_RX;
	dmaConfig.dmaInt       = CSL_DMA_INTERRUPT_ENABLE;
	dmaConfig.chanDir      = CSL_DMA_READ;
	dmaConfig.trfType      = CSL_DMA_TRANSFER_IO_MEMORY;
	dmaConfig.dataLen      = CSL_I2S_DMA_BUF_LEN*4; // convert from 32 bit word count to bytes
	dmaConfig.srcAddr      = (Uint32)&(hI2s->hwRegs->I2SRXLT0); // 0x2A28 
	dmaConfig.destAddr     = (Uint32)i2sDmaReadLeftBuff;
	dmaLeftRxHandle = CSL_configDmaForI2s(CSL_DMA_CHAN4);
	if(dmaLeftRxHandle == NULL)
	{
		printf("DMA Config for I2S Read Failed!\n!");
		return(CSL_TEST_FAILED);
	}
	
	/* Configure DMA channel 5  for I2S2 Read of right channel */
#if (defined(CHIP_C5505_C5515) || defined(CHIP_C5504_C5514))
	dmaConfig.pingPongMode = CSL_DMA_PING_PONG_ENABLE;
#else
    // DJH sanity check because we want to use the C5515
    #error "Must define CHIP_C5505_C5515"
#endif
#if _USE_I2S_RIGHT 
    // Change the config parameters as necessary for the right channel
	dmaConfig.srcAddr      = (Uint32)&(hI2s->hwRegs->I2SRXRT0); // 0x2A28 
	dmaConfig.destAddr     = (Uint32)i2sDmaReadRightBuff;
	dmaRightRxHandle = CSL_configDmaForI2s(CSL_DMA_CHAN5);
	if(dmaRightRxHandle == NULL)
	{
		printf("DMA Config for I2S Read Failed!\n!");
		return(CSL_TEST_FAILED);
	}	
#endif 


	status = DMA_start(dmaLeftRxHandle);
	if(status != CSL_SOK)
	{
		printf("I2S Dma Start Left Failed!!\n");
		return(result);
	}
	I2S_transEnable(hI2s, TRUE);
#if _USE_I2S_RIGHT
	status = DMA_start(dmaRightRxHandle);
	if(status != CSL_SOK)
	{
		printf("I2S Dma Start Right Failed!!\n");
		return(result);
	}
#endif
    // run forever here    	
    for(;;) {

       volatile int rtcSecSnap;
        
    
        rtcSecSnap =CSL_RTC_REGS->RTCSEC;
        if (ledState) {
            HAL_XF_LED_ON;
        } else {
            HAL_XF_LED_OFF;
        }
        ledState = !ledState;
        while (rtcSecSnap==CSL_RTC_REGS->RTCSEC) {
          // do nothing    
        }	
    }
}


/*
	This is functionality to receive data via the slave interface
	in stereo, DSP format, and via DMA

	Function returns:
	CSL_TEST_FAILED                -Failure
	CSL_TEST_PASSED                -Success
*/
Int16 i2s_intr_sampleSlave(void)
{
	Int16 			status = CSL_TEST_FAILED;
	Int16 			result;
	CSL_I2sHandle	hI2s;
	I2S_Config		hwConfig;
	Uint16 			looper;
    int ledState = 0;
    
    
    IRQ_globalDisable();

	IRQ_clearAll();

	IRQ_disableAll();

	IRQ_setVecs((Uint32)&VECSTART);
    // configure the i2s2 interrupt handler
	IRQ_clear(RCV2_EVENT);
	IRQ_plug (RCV2_EVENT, &i2s2rx_isr);
	IRQ_enable(RCV2_EVENT);
	IRQ_globalEnable();



	/* Initialize data buffers */
	for(looper=0; looper < CSL_I2S_DMA_BUF_LEN; looper++)
	{
		//i2sDmaWriteLeftBuff[looper] = 0x12345678;
		i2sDmaReadLeftBuff[looper]	= 0;
		//i2sDmaWriteRightBuff[looper] = 0x12345678;
		i2sDmaReadRightBuff[looper]	= 0;
	}

	for(looper=0; looper < SENSORDATA_BUFLEN; looper++)
	{
      mSensorBufferRight[looper] = mSensorBufferLeft[looper] = 0;
	}

	/** Open the device with instance 2							*/
	hI2s = I2S_open(I2S_INSTANCE2, DMA_POLLED, 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;
//#if _UNITTEST_I2S_
//    hwConfig.loopBackMode       = I2S_LOOPBACK_ENABLE;
//    hwConfig.i2sMode            = I2S_MASTER;
//#else
    hwConfig.loopBackMode       = I2S_LOOPBACK_DISABLE;
    hwConfig.i2sMode            = I2S_SLAVE;
//#endif // _UNITTEST_I2S_
    hwConfig.fsPol              = I2S_FSPOL_LOW;
    hwConfig.clkPol             = I2S_RISING_EDGE;
    hwConfig.datadelay          = I2S_DATADELAY_ONEBIT;
    hwConfig.datapack           = I2S_DATAPACK_DISABLE;
    hwConfig.signext            = I2S_SIGNEXT_DISABLE;
    hwConfig.wordLen            = I2S_WORDLEN_32;
    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");
	}
    // Set the DSP Format flag..The i2s driver by default clears this bit
    hI2s->hwRegs->I2SSCTRL |= CSL_I2S_I2SSCTRL_FRMT_MASK;
    
    // Enable only the frame error and the overrun error bits
    hI2s->hwRegs->I2SINTMASK = (Uint16) (CSL_I2S_I2SINTMASK_FERR_MASK|CSL_I2S_I2SINTMASK_OUERR_MASK) ;

	I2S_transEnable(hI2s, TRUE);

    // run forever here    	
    for(;;) {

       volatile int rtcSecSnap;
        
    
        rtcSecSnap =CSL_RTC_REGS->RTCSEC;
        if (ledState) {
            HAL_XF_LED_ON;
        } else {
            HAL_XF_LED_OFF;
        }
        ledState = !ledState;
        while (rtcSecSnap==CSL_RTC_REGS->RTCSEC) {
          // do nothing    
        }	
    }
}



/*
	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
*/
Int16 i2s_DMA_sample(void)
{
	Int16 			status = CSL_TEST_FAILED;
	Int16 			result;
	CSL_I2sHandle	hI2s;
	I2S_Config		hwConfig;
	Uint16 			looper;

	/* Initialize data buffers */
	for(looper=0; looper < CSL_I2S_DMA_BUF_LEN; looper++)
	{
		i2sDmaWriteLeftBuff[looper] = 0x12345678;
		i2sDmaReadLeftBuff[looper]	= 0;
		i2sDmaWriteRightBuff[looper] = 0x12345678;
		i2sDmaReadRightBuff[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, DMA_POLLED, 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");
	}

	/* Configure DMA channel  for I2S write */
#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_1WORD;
	dmaConfig.trigger      = CSL_DMA_EVENT_TRIGGER;
	dmaConfig.dmaEvt       = CSL_DMA_EVT_I2S0_TX;
	dmaConfig.dmaInt       = CSL_DMA_INTERRUPT_DISABLE;
	dmaConfig.chanDir      = CSL_DMA_WRITE;
	dmaConfig.trfType      = CSL_DMA_TRANSFER_IO_MEMORY;
	dmaConfig.dataLen      = 4;
	dmaConfig.srcAddr      = (Uint32)i2sDmaWriteLeftBuff;
	dmaConfig.destAddr     = (Uint32)(0x2808);
	dmaLeftTxHandle = CSL_configDmaForI2s(CSL_DMA_CHAN0);
	if(dmaLeftTxHandle == NULL)
	{
		printf("DMA Config for I2S Write Failed!\n!");
		return(CSL_TEST_FAILED);
	}

	I2S_transEnable(hI2s, TRUE);

	status = DMA_start(dmaLeftTxHandle);
	if(status != CSL_SOK)
	{
		printf("I2S Dma Write Failed!!\n");
		return(result);
	}
	while(DMA_getStatus(dmaLeftTxHandle));

	/* Configure DMA channel  for I2S write */
#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_1WORD;
	dmaConfig.trigger      = CSL_DMA_EVENT_TRIGGER;
	dmaConfig.dmaEvt       = CSL_DMA_EVT_I2S0_TX;
	dmaConfig.dmaInt       = CSL_DMA_INTERRUPT_DISABLE;
	dmaConfig.chanDir      = CSL_DMA_WRITE;
	dmaConfig.trfType      = CSL_DMA_TRANSFER_IO_MEMORY;
	dmaConfig.dataLen      = 4;
	dmaConfig.srcAddr      = (Uint32)i2sDmaWriteRightBuff;
	dmaConfig.destAddr     = (Uint32)(0x280C);
	dmaRightTxHandle = CSL_configDmaForI2s(CSL_DMA_CHAN0);
	if(dmaRightTxHandle == NULL)
	{
		printf("DMA Config for I2S Write Failed!\n!");
		return(CSL_TEST_FAILED);
	}

	I2S_transEnable(hI2s, TRUE);

	status = DMA_start(dmaRightTxHandle);
	if(status != CSL_SOK)
	{
		printf("I2S Dma Write Failed!!\n");
		return(result);
	}
	while(DMA_getStatus(dmaRightTxHandle));

	/* Configure DMA channel  for I2S Read */
#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_1WORD;
	dmaConfig.trigger      = CSL_DMA_EVENT_TRIGGER;
	dmaConfig.dmaEvt       = CSL_DMA_EVT_I2S0_RX;
	dmaConfig.dmaInt       = CSL_DMA_INTERRUPT_DISABLE;
	dmaConfig.chanDir      = CSL_DMA_READ;
	dmaConfig.trfType      = CSL_DMA_TRANSFER_IO_MEMORY;
	dmaConfig.dataLen      = 4;
	dmaConfig.srcAddr      = (Uint32)(0x2828);
	dmaConfig.destAddr     = (Uint32)i2sDmaReadLeftBuff;
	dmaLeftRxHandle = CSL_configDmaForI2s(CSL_DMA_CHAN0);
	if(dmaLeftRxHandle == NULL)
	{
		printf("DMA Config for I2S Read Failed!\n!");
		return(CSL_TEST_FAILED);
	}

	status = DMA_start(dmaLeftRxHandle);
	if(status != CSL_SOK)
	{
		printf("I2S Dma Read Failed!!\n");
		return(result);
	}
	while(DMA_getStatus(dmaLeftRxHandle));

	/* Configure DMA channel  for I2S Read */
#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_1WORD;
	dmaConfig.trigger      = CSL_DMA_EVENT_TRIGGER;
	dmaConfig.dmaEvt       = CSL_DMA_EVT_I2S0_RX;
	dmaConfig.dmaInt       = CSL_DMA_INTERRUPT_DISABLE;
	dmaConfig.chanDir      = CSL_DMA_READ;
	dmaConfig.trfType      = CSL_DMA_TRANSFER_IO_MEMORY;
	dmaConfig.dataLen      = 4;
	dmaConfig.srcAddr      = (Uint32)(0x282C);
	dmaConfig.destAddr     = (Uint32)i2sDmaReadRightBuff;
	dmaRightRxHandle = CSL_configDmaForI2s(CSL_DMA_CHAN0);
	if(dmaRightRxHandle == NULL)
	{
		printf("DMA Config for I2S Read Failed!\n!");
		return(CSL_TEST_FAILED);
	}

	I2S_transEnable(hI2s, TRUE);

	status = DMA_start(dmaRightRxHandle);
	if(status != CSL_SOK)
	{
		printf("I2S Dma Read Failed!!\n");
		return(result);
	}
	while(DMA_getStatus(dmaRightRxHandle));

	I2S_transEnable(hI2s, FALSE);
	/** Reset the registers										*/
	result = I2S_reset(hI2s);

	if(result != CSL_SOK)
	{
		status = CSL_TEST_FAILED;
		return (status);
	}
	else
	{
		printf ("I2S Reset Successful\n");
	}

	/** Close the operation										*/
	result = I2S_close(hI2s);

	if(result != CSL_SOK)
	{
		status = CSL_TEST_FAILED;
		return (status);
	}
	else
	{
		printf ("I2S Close Successful\n");
	}

	/* Swap words in I2S write buffer
	   This will make the data in write buffer get back to original values
	   after that write buffer can be used for validating the read buffer
	   This sep is required only incase of comparing read and write buffers */
	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);
	}

	/** Compare the read and write buffer						*/
	for(looper=0; looper < CSL_I2S_DMA_BUF_LEN; looper++)
	{
		if(i2sDmaWriteLeftBuff[looper] != i2sDmaReadLeftBuff[looper])
		{
			printf("I2S Read & Write Buffers doesn't Match!!!\n");
			status = CSL_TEST_FAILED;
			return(status);
		}
	}

	if(looper == CSL_I2S_DMA_BUF_LEN)
	{
		printf("I2S Read & Write Buffers Match!!!\n");
	}

	status = CSL_TEST_PASSED;
	return (status);
}

/*
 This is the main function to call sample program
*/
   /////INSTRUMENTATION FOR BATCH TESTING -- Part 1 --   
   /////  Define PaSs_StAtE variable for catching errors as program executes.
   /////  Define PaSs flag for holding final pass/fail result at program completion.
        volatile Int16 PaSs_StAtE = 0x0001; // Init to 1. Reset to 0 at any monitored execution error.
        volatile Int16 PaSs = 0x0000; // Init to 0.  Updated later with PaSs_StAtE when and if
   /////                                  program flow reaches expected exit point(s).
   /////
void main(void)
{
	Int16    status;
    BoardSetup();
	printf("CSL I2S DMA MODE TEST!\n\n");

	// status = i2s_DMA_sample();  // uncomment this for the spi loopback test
  //  status = i2s_DMA_sampleSlave(); // uncomment ths for spi DMA slave test
  status = i2s_intr_sampleSlave(); // uncomment for spi interrupt slave test
	if(status != CSL_TEST_PASSED)
	{
		printf("\nCSL I2S DMA MODE TEST FAILED!!\n\n");
   /////INSTRUMENTATION FOR BATCH TESTING -- Part 2 --   
   /////  Reseting PaSs_StAtE to 0 if error detected here.
        PaSs_StAtE = 0x0000; // Was intialized to 1 at declaration.
   /////
	}
	else
	{
		printf("\nCSL I2S DMA MODE TEST PASSED!\n\n");
	}
   /////INSTRUMENTATION FOR BATCH TESTING -- Part 3 -- 
   /////  At program exit, copy "PaSs_StAtE" into "PaSs".
        PaSs = PaSs_StAtE; //If flow gets here, override PaSs' initial 0 with 
   /////                   // pass/fail value determined during program execution.
   /////  Note:  Program should next exit to C$$EXIT and halt, where DSS, under
   /////   control of a host PC script, will read and record the PaSs' value.  
   /////
}

static volatile Uint16 mnPingErr = 0;
static volatile Uint16 mPongLeftLast = 0;
static volatile Uint16 mPongRightLast = 0;
static volatile Uint16 mnPings = 0;
static volatile Uint16 mnPongs = 0;


static volatile Uint16 mLeftIdx = 0;
static volatile Uint16 mRightIdx = 0;
static volatile Uint32 isrEntryCount = 0;
interrupt void dma_isr(void)
{
	int idx;
   
    int pong; //=CSL_DMA_DMACH0TCR2_LTSTATUS_MASK for pong, =0 for ping
  	int ifrValue = CSL_SYSCTRL_REGS->DMAIFR;
    //HAL_XF_LED_OFF;
    // turn led on'
    LEDBANK0_LEDON(LEDBANK0_LED0_MASK);

#if 1
    // Determine if the ping or pong register was filled
	  if (CSL_SYS_DMAIFR_DMA1CH0IF_MASK & ifrValue) {
	  	// reset the source address to point to the I2SRXLT0 register 
	  	CSL_DMA1_REGS->DMACH0SSAL = (Uint16) &CSL_I2S2_REGS->I2SRXLT0;  // same as &(hI2s->hwRegs->I2SRXLT0)
	  	
        // we do the equivalent of DMA_getLastTransferType() to
        // determine if it's the ping or the pong buffer
        pong = (CSL_DMA1_REGS->DMACH0TCR2 & CSL_DMA_DMACH0TCR2_LTSTATUS_MASK);
        idx = pong ? kDMA_I2S2_PING_DBLWORDS : 0; // LTSTATUS=1 for pong, =0 for ping
        if (mPongLeftLast==pong) {
          mnPingErr++;  
        }
        if (idx) {
          mnPings++;	
        } else {
          mnPongs++;       	
        }
        
        mPongLeftLast = pong;
        // per the audio filter demo provided by TI, we must manually set the new destination
        // address 
        //CSL_DMA1_REGS->DMACH0TCR2
        
        // copy the data into the bufffer
        mSensorBufferLeft[mLeftIdx++] = i2sDmaReadLeftBuff[idx++];
        mSensorBufferLeft[mLeftIdx] = i2sDmaReadLeftBuff[idx];
        mLeftIdx = (mLeftIdx + 1)% SENSORDATA_BUFLEN;
        CSL_SYSCTRL_REGS->DMAIFR = CSL_SYS_DMAIFR_DMA1CH0IF_MASK;
	  } 
#if 0
    // Determine if the ping or pong register was filled
	  if (CSL_SYS_DMAIFR_DMA1CH1IF_MASK & ifrValue) {
        // we do the equivalent of DMA_getLastTransferType() to
        // determine if it's the ping or the pong buffer
        pong = (CSL_DMA1_REGS->DMACH1TCR2 & CSL_DMA_DMACH1TCR2_LTSTATUS_MASK);
        idx = pong ? kDMA_I2S2_PING_DBLWORDS : 0; // LTSTATUS=1 for pong, =0 for ping
        if (mPongRightLast==pong) {
          mnPingErr++;  
        }
        mPongRightLast = pong;
        // copy the data into the our sensor buffer to just look at samples
        mSensorBufferRight[mRightIdx] = i2sDmaReadRightBuff[idx];
        mRightIdx = (mRightIdx + 1) % SENSORDATA_BUFLEN;
        CSL_SYSCTRL_REGS->DMAIFR = CSL_SYS_DMAIFR_DMA1CH1IF_MASK;
	  } 
#endif
#endif 
	// CSL_SYSCTRL_REGS->DMAIFR = ifrValue;  // Clear the bits for this dma channel being service
	//++count;
	++isrEntryCount;
	// turn led0 off
    LEDBANK0_LEDOFF(LEDBANK0_LED0_MASK);;
}

static volatile Uint16 mnFrameErr = 0;
static volatile Uint16 mnOverrunErr = 0;
interrupt void i2s2rx_isr(void) {
  	// note all the interrupt flag bits are cleared on this read (not just RX)
    // this is not an issue for us, since we only use the i2s rx line. However, anyone wanting to use
    // the transmit would have to process the transmit if the bit was set here.
  	int ifrValue = CSL_I2S2_REGS->I2SINTFL;	
  	//volatile ioport Uint32* const pRxVal= (Uint32*)&CSL_I2S2_REGS->I2SRXLT0;
	// turn led on'
    LEDBANK0_LEDON(LEDBANK0_LED0_MASK);
    
	// if (ifrValue & CSL_I2S_I2SINTFL_XMITSTFL_MASK) {}  // transmit stereo  -- ignore
	// if (ifrValue & CSL_I2S_I2SINTFL_XMITMONFL_MASK) {} // transmit mono  -- ignore
	if (ifrValue & CSL_I2S_I2SINTFL_RCVSTFL_MASK) { // receive stereo  
        // copy the data into the buffer
        // Using 32 bit pointer
        // is highly inefficient because this will be split into two separate 16 bit reads from
        // the i/o port address since the CPU only has a 16 bit wide i/o port. Secondly we need to swap
        // words becsause the LSW is read first then the MSW 
        // mSensorBufferLeft[mLeftIdx] = *pRxVal;
        mSensorIruptBuffer[mLeftIdx++] = CSL_I2S2_REGS->I2SRXLT1;
        mSensorIruptBuffer[mLeftIdx++] = CSL_I2S2_REGS->I2SRXLT0;
        mSensorIruptBuffer[mLeftIdx++] = CSL_I2S2_REGS->I2SRXRT1;
        mSensorIruptBuffer[mLeftIdx] = CSL_I2S2_REGS->I2SRXRT0;
        mLeftIdx = (mLeftIdx + 1)% SENSORDATA_BUFWORDS;	// handle the buffer wrap	
	}
	// if (ifrValue & CSL_I2S_I2SINTFL_RCVMONFL_MASK) {} // receive mono  -- ignore
	if (ifrValue & CSL_I2S_I2SINTFL_FERRFL_MASK) { // frame sync error  
	  mnFrameErr++;	
	}
	if (ifrValue & CSL_I2S_I2SINTFL_OUERRFL_MASK) { // overrun error  
	  mnOverrunErr++;	
	}

	
	++isrEntryCount;
	// turn led0 off
    LEDBANK0_LEDOFF(LEDBANK0_LED0_MASK);	
}