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.

TMDXEVM5515: Why does the C5515 DMA can only entry interrupt once with RELOAD Enable?

Part Number: TMDXEVM5515

I want to record/play audio using I2S with DMA working at Ping-Pong mode.

Before that I do a test of I2S and DMA transfer.The DAM setting is as follows:

    /* Configure DMA channel 0 for I2S left channel read */
    dmaConfig.pingPongMode  = CSL_DMA_PING_PONG_ENABLE;
    dmaConfig.autoMode      = CSL_DMA_AUTORELOAD_ENABLE;
    dmaConfig.burstLen      = CSL_DMA_TXBURST_1WORD;
    dmaConfig.trigger       = CSL_DMA_EVENT_TRIGGER;

    dmaConfig.dmaEvt        = CSL_DMA_EVT_I2S2_TX;

    dmaConfig.dmaInt        = CSL_DMA_INTERRUPT_ENABLE;
    dmaConfig.chanDir       = CSL_DMA_WRITE;
    dmaConfig.trfType       = CSL_DMA_TRANSFER_IO_MEMORY;
    dmaConfig.dataLen       = NUM_SAMP_PER_MS*NUM_MS_PER_FRAME*2; // two frames

    dmaConfig.destAddr      = (Uint32)&CSL_I2S2_REGS->I2STXLT0;

    dmaConfig.srcAddr       = (Uint32)i2sDmaReadBufLeft;

    /* Open DMA ch0 for I2S left channel read */
    dmaLeftRxHandle = DMA_open(DMA_CHAN_L, &dmaObj0,&status);//DMA_CHAN_L = 4
    if (dmaLeftRxHandle == NULL)
    {
    	LOG_printf(&trace,"DMA_open CH4 Failed \n");
        dmaLeftRxHandle = NULL;
    }

    /* Configure DMA channel */
    status = DMA_config(dmaLeftRxHandle, &dmaConfig);
    if (status != CSL_SOK)
    {
    	LOG_printf(&trace,"DMA_config CH4 Failed \n");
        dmaLeftRxHandle = NULL;
    }

// DMA ISR
void DmaIsr(void)
{
    int ifrValue;
    Uint32 i;
    CSL_Status 	status;

  	ifrValue = CSL_SYSCTRL_REGS->DMAIFR;
	CSL_SYSCTRL_REGS->DMAIFR |= ifrValue;
	if ((DMA_getLastTransferType (dmaLeftRxHandle, &status)) == 1)
	{
		// Pong传输完成,标志位1
    	for (i=0; i<2; i++)
        {
//    		dmaPongSrcBuf_L[i]  = dmaPongDstBuf_L[i];
//    		dmaPongSrcBuf_R[i]  = dmaPongDstBuf_R[i];
        }
	}
	else
	{
		// Ping传输完成,标志位0
    	for (i=0; i<2; i++)
        {
//    		dmaPingSrcBuf_L[i]  = dmaPingDstBuf_L[i];
//    		dmaPingSrcBuf_R[i]  = dmaPingDstBuf_R[i];
        }
	}
}

It word in DSP/BIOS  environment, I have set the DmaIsr() as HWI_INT8's function in .tcf file.

Why does it can only entry the ISR once?

In the only Task initTask(), it has a while(1) like this:

    while(1) {
//      	ifrValue = CSL_SYSCTRL_REGS->DMAIFR;
//      	if(ifrValue) {
//      		CSL_SYSCTRL_REGS->DMAIFR |= ifrValue;
//      		if ((DMA_getLastTransferType (dmaLeftRxHandle, &status)) == 1)
//      		{
//      			// Pong传输完成,标志位1
//      	    	//for (i=0; i<2; i++);
//      	    	CNT1++;
//      		}
//      		else
//      		{
//      			// Ping传输完成,标志位0
//      	    	//for (i=0; i<2; i++);
//      	    	CNT2++;
//      		}
    }

if I uncomment the code, and debug it,Whenever I hold, the value of CNT1 is equal CNT2±1.It means that the DMA transfer is Still continue, but it DOSE NOT cause an DMA interrupt.

The main file is in the attachment  tsk.c.

tsk.c
/*
 *  Copyright 2010 by Texas Instruments Incorporated.
 *  @(#) DSP/BIOS_Examples 5,4,1 02-08-2010 (biosEx-j14)
 */
/*
 *  ======== tsk.c =======
 *  In this example, 3 tasks have been created with the Configuration
 *  Tool.  Each task has a computation loop consisting of a LOG_printf()
 *  followed by a TSK_yield().  This causes a round robin scheduling for
 *  these tasks of equal priority.
 */

#include <std.h>

#include <log.h>
#include <tsk.h>
#include <prd.h>
#include <mem.h>
#include <que.h>
#include <sem.h>

#include "csl_i2s.h"
#include "csl_dma.h"
#include "csl_intc.h"
#include "tskcfg.h"


#include "my_gpio.h"
#include "spi_eeprom.h"
#include "registers.h"
#include "sysctrl.h"
#include "menu_bmp.h"
#include "lcd12864.h"
#include "lcd_app.H"
#include "setting_PLL.h"
#include "key.h"
#include "SDRAM.h"

#include "codec_aic3254.h"

#define ST1_55      *(volatile unsigned *)0x0003

#define NUMMSGS		492
#define NUMWRITERS  1    /* number of writer tasks created with Config Tool */
#define WORDS_PER_BUFF	8192

#define TIMEOUT	100

//typedef struct MsgObj {
//    QUE_Elem    elem;        /* first field for QUE */
//    Uint32      sdramAddr;
//} MsgObj, *Msg;

typedef struct MsgObj {
    QUE_Elem    elem;        /* first field for QUE */
    Int         id;          /* writer task id */
    Uint32      sdramAddr;         /* message value */
} MsgObj, *Msg;

extern Int SEG0;
extern Int SEG1;

extern QUE_Obj msgQueue;
extern QUE_Obj freeQueue;

Void task(Arg id_arg);  /* Function for tasks created with Config Tool */ 




#define I2S_INSTANCE    ( I2S_INSTANCE2 )
#define DMA_CHAN_L      ( CSL_DMA_CHAN4 )
#define DMA_CHAN_R      ( CSL_DMA_CHAN5 )

#define I2S_DMA_BUF_LEN         ( FRAME_LEN*2 )
/* PLL output MHz setting */
#define PLL_MHZ                 ( 100 )

#define NUM_SAMP_PER_MS         ( 16 )  // samples per msec
#define NUM_MS_PER_FRAME        ( 20 )  // msec per frame
#define FRAME_LEN               ( NUM_SAMP_PER_MS * NUM_MS_PER_FRAME)   // frame length

CSL_I2sHandle hI2s;

Uint16 *i2sDmaReadBufLeft;
Uint16 *i2sDmaReadBufRight;

CSL_DMA_Handle dmaLeftRxHandle;
CSL_DMA_Handle dmaRightRxHandle;
CSL_DMA_ChannelObj dmaObj0, dmaObj1;
volatile Uint16 dmaFrameCount = 0;

const unsigned short sine_750Hz_48kHzFs[64] =
{
0x0000,0x8c0c,0xf918,0x2825,0xfb30,0x563c,0x1c47,0x3351,
0x825a,0xf162,0x6d6a,0xe270,0x4176,0x7c7a,0x897d,0x617f,
0xff7f,0x617f,0x897d,0x7c7a,0x4176,0xe270,0x6d6a,0xf162,
0x825a,0x3351,0x1c47,0x563c,0xfb30,0x2825,0xf918,0x8c0c,
0x0000,0x74f3,0x07e7,0xd8da,0x05cf,0xaac3,0xe4b8,0xcdae,
0x7ea5,0x0f9d,0x9395,0x1e8f,0xbf89,0x8485,0x7782,0x9f80,
0x0180,0x9f80,0x7782,0x8485,0xbf89,0x1e8f,0x9395,0x0f9d,
0x7ea5,0xcdae,0xe4b8,0xaac3,0x05cf,0xd8da,0x07e7,0x74f3
};

// Initializes DMA
CSL_Status DmaInit(void);
// DMA ISR
void DmaIsr(void);
// I2S and DMA initialization
CSL_Status I2sDmaInit(void);



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


/*
 * menu_display_logo
 * ��ʾLOGO
 * */
void menu_display_logo(void)
{
	Uint8 i = 0, j = 0;
	for (i = 0; i < 8; i++) {
		lcd_set_pos(0,i);
		for (j = 0; j < 128; j++){
			lcd_write_data(start_logo_img[i][j]);
		}
	}
}

/*
 *  ======== main ========
 */
Void main()
{
	//Int temp = 0;
	// ʹ������ʱ��,����MASTER_CLK��ϵͳʱ��,����ʹ��,���ǽ�������״̬
	PeripheralClkEnableOnly(PERIPH_CLK_MASTER_CLK
							| PERIPH_CLK_SPI		// ʹ��SPIģ��
							| PERIPH_CLK_UART		// UART
							| PERIPH_CLK_DMA0		// DMA0
							| PERIPH_CLK_DMA1		// DMA1
							| PERIPH_CLK_DMA2		// DMA2
							| PERIPH_CLK_DMA3		// DMA3
							| PERIPH_CLK_MMCSD0		// MMCSD0
							| PERIPH_CLK_I2C		// I2C
							| PERIPH_CLK_IIS2		// I2S2
							| PERIPH_CLK_TIMER0		// TIMER0
							| PERIPH_CLK_TIMER1		// TIMER1
							| PERIPH_CLK_TIMER2		// TIMER2
							| PERIPH_CLK_EMIF		// EMIF
							| PERIPH_CLK_SARADC		// ADC
							);
//	// ʹ����������,�����á���������������TEST������������������
//	CSL_SYSCTRL_REGS->PCGCR1 = 0x0000;
//	CSL_SYSCTRL_REGS->PCGCR2 = 0x0000;

	ProgramPLL_120MHz();
	my_gpio_init();
	spi_eeprom_init();
	sar_adc_key_init();
	my_GPIO_write(LCD_BK_PIN, 0);
	lcd12864_init();
	menu_display_logo();
	SDRAM_init();
	LOG_printf(&trace, "DSP/BIOS Start...");
}
/*
 *  ======== initTask ========
 */
    MsgObj      *msg;
    Uint32 CNT1=0,CNT2=0;
Void initTask()
{
	Uint16 ifrValue;
    Uint32         i;
    CSL_Status status;
    Uns         mask;

    mask = TRC_LOGTSK | TRC_LOGSWI | TRC_STSSWI | TRC_LOGCLK;
    TRC_enable(TRC_GBLHOST | TRC_GBLTARG | mask);

    i2sDmaReadBufLeft = (Uint16 *)MEM_alloc(SEG1, I2S_DMA_BUF_LEN * sizeof(Uint16), 0);//SEG1 is SARAM
    if (i2sDmaReadBufLeft == MEM_ILLEGAL) {
    	LOG_printf(&trace, "Memory allocation failed!");
        SYS_abort("Memory allocation failed!\n");
    }
    i2sDmaReadBufRight = (Uint16 *)MEM_alloc(SEG1, I2S_DMA_BUF_LEN * sizeof(Uint16), 0);
    if (i2sDmaReadBufRight == MEM_ILLEGAL) {
    	LOG_printf(&trace, "Memory allocation failed!");
        SYS_abort("Memory allocation failed!\n");
    }

	/* Copy two sine wave frames into DMA buffers */
	for (i=0; i<I2S_DMA_BUF_LEN; i++)
	{
		 i2sDmaReadBufLeft[i]  = (sine_750Hz_48kHzFs[i%64]);
		 i2sDmaReadBufRight[i] = (sine_750Hz_48kHzFs[i%64]);
	}

    // Initialize DMA
    status = DmaInit();
    if (status != CSL_SOK)
    {
    	LOG_printf(&trace, "ERROR: Unable to initialize DMA\n");
    	SYS_abort("DmaInit failed!\n");
    }

    // Initialize I2S with DMA
    status = I2sDmaInit();
    if (status != CSL_SOK)
    {
    	LOG_printf(&trace, "ERROR: Unable to initialize I2S and DMA\n");
    	SYS_abort("I2sDmaInit failed!\n");
    }

    /* Intialize AIC3204 codec */
    status = AIC3254_init(48000, 48000, PLL_MHZ);
    if (status != CSL_SOK)
    {
    	LOG_printf(&trace, "ERROR: Unable to initialize AIC3204\n");
    	SYS_abort("AIC3254_init failed!\n");
    }
    while(1) {
//      	ifrValue = CSL_SYSCTRL_REGS->DMAIFR;
//      	if(ifrValue) {
//      		CSL_SYSCTRL_REGS->DMAIFR |= ifrValue;
//      		if ((DMA_getLastTransferType (dmaLeftRxHandle, &status)) == 1)
//      		{
//      			// Pong�������,��־λ1
//      	    	//for (i=0; i<2; i++);
//      	    	CNT1++;
//      		}
//      		else
//      		{
//      			// Ping�������,��־λ0
//      	    	//for (i=0; i<2; i++);
//      	    	CNT2++;
//      		}
    }
}
/*
 * PRD_10ms
 * ÿ10ms����һ�Σ����ڸ�����ɨ���ṩ���ڲο�
 * */
void PRD_10ms()
{
	key.scan_flag = 1;
}

/*
 * PRD_1000ms
 * ÿ1s����һ�Σ����ڸ���������ṩ���ڲο�
 * */
void PRD_1000ms()
{

}

//*****************************************************************************
// DmaInit
//*****************************************************************************
//  Description: Initializes DMA, enables DMA interrupts
//
//  Arguments:
//      none
//
//  Return:
//      CSL_Status: CSL_SOK - DMA initialization successful
//                  other   - DMA initialization unsuccessful
//
//*****************************************************************************
CSL_Status DmaInit(void)
{
    Uint16 ifrValue;
    CSL_Status status;

    // Disable DMA interrupt
    IRQ_disable(DMA_EVENT); // �DZ���

    // Clear DMA interrupt
    IRQ_clear(DMA_EVENT); // �DZ���

    // Disable DMA interrupts
    CSL_SYSCTRL_REGS->DMAIER = 0x0000; // �DZ���

    // Clear pending DMA interrupts
    ifrValue = CSL_SYSCTRL_REGS->DMAIFR; // �DZ���
    CSL_SYSCTRL_REGS->DMAIFR |= ifrValue; // �DZ���

    // Plug in DMA ISR
//    IRQ_plug(DMA_EVENT, &DmaIsr); // ��.tcf��������ISR����,���ﲻ��Ҫ������

    // DMA initialization
    status = DMA_init(); // ���룬�ڵ�������DMA��CSL����ǰ��Ҫ�ȵ��øú���
    if (status != CSL_SOK)
    {
        //printf("DMA_init() fail, status=%d\n", status);
        return status;
    }


    return CSL_SOK;
}

// DMA ISR
void DmaIsr(void)
{
    int ifrValue;
    Uint32 i;
    CSL_Status 	status;

  	ifrValue = CSL_SYSCTRL_REGS->DMAIFR;
	CSL_SYSCTRL_REGS->DMAIFR |= ifrValue;
	if ((DMA_getLastTransferType (dmaLeftRxHandle, &status)) == 1)
	{
		// Pong�������,��־λ1
    	for (i=0; i<2; i++)
        {
//    		dmaPongSrcBuf_L[i]  = dmaPongDstBuf_L[i];
//    		dmaPongSrcBuf_R[i]  = dmaPongDstBuf_R[i];
        }
	}
	else
	{
		// Ping�������,��־λ0
    	for (i=0; i<2; i++)
        {
//    		dmaPingSrcBuf_L[i]  = dmaPingDstBuf_L[i];
//    		dmaPingSrcBuf_R[i]  = dmaPingDstBuf_R[i];
        }
	}
}
//*****************************************************************************
// I2sDmaInit
//*****************************************************************************
//  Description:
//      Configures and starts I2S with DMA
//
//  Parameters:
//      hI2s                - I2S handle (global)
//      dmaLeftRxHandle     - handle for I2S left DMA (global)
//      dmaRightRxHandle    - handle for I2S right DMA (global)
//
//      CSL_Status: CSL_SOK - I2S & DMA initialization successful
//                  other   - I2S & DMA initialization unsuccessful
//
//*****************************************************************************
CSL_Status I2sDmaInit(void)
{
    I2S_Config hwConfig;
    CSL_DMA_Config dmaConfig;
    CSL_Status status;

    /* DMA engine initialization */
    /* Open the device with instance 2 (AIC3204 is connected to I2S2 on C5515 EVM) */
    hI2s = I2S_open(I2S_INSTANCE, DMA_POLLED, I2S_CHAN_STEREO);
    if(NULL == hI2s)
    {
        status = CSL_ESYS_FAIL;
        return (status);
    }
    else
    {
    	LOG_printf(&trace,"I2S Module Instance opened successfully\n");
    }

    /* Set the value for the configure structure */
    hwConfig.dataFormat     = I2S_DATAFORMAT_LJUST;
    hwConfig.dataType       = I2S_STEREO_ENABLE;
    hwConfig.loopBackMode   = I2S_LOOPBACK_DISABLE;
    hwConfig.fsPol          = I2S_FSPOL_LOW;
    hwConfig.clkPol         = I2S_FALLING_EDGE;
    hwConfig.datadelay      = I2S_DATADELAY_ONEBIT;
    hwConfig.datapack       = I2S_DATAPACK_DISABLE;
    hwConfig.signext        = I2S_SIGNEXT_DISABLE;
    hwConfig.wordLen        = I2S_WORDLEN_16;
    hwConfig.i2sMode        = I2S_SLAVE;
    hwConfig.clkDiv         = I2S_CLKDIV2; // don't care for slave mode
    hwConfig.fsDiv          = I2S_FSDIV32; // don't care for slave mode
    hwConfig.FError         = I2S_FSERROR_DISABLE;
    hwConfig.OuError        = I2S_OUERROR_DISABLE;

    /* Configure hardware registers */
    status = I2S_setup(hI2s, &hwConfig);
    if(status != CSL_SOK)
    {
        return (status);
    }
    else
    {
    	LOG_printf(&trace,"I2S Module Configured successfully\n");
    }

    /* Configure DMA channel 0 for I2S left channel read */
    dmaConfig.pingPongMode  = CSL_DMA_PING_PONG_ENABLE;
    dmaConfig.autoMode      = CSL_DMA_AUTORELOAD_ENABLE;
    dmaConfig.burstLen      = CSL_DMA_TXBURST_1WORD;
    dmaConfig.trigger       = CSL_DMA_EVENT_TRIGGER;

    dmaConfig.dmaEvt        = CSL_DMA_EVT_I2S2_TX;

    dmaConfig.dmaInt        = CSL_DMA_INTERRUPT_ENABLE;
    dmaConfig.chanDir       = CSL_DMA_WRITE;
    dmaConfig.trfType       = CSL_DMA_TRANSFER_IO_MEMORY;
    dmaConfig.dataLen       = NUM_SAMP_PER_MS*NUM_MS_PER_FRAME*2; // two frames

    dmaConfig.destAddr      = (Uint32)&CSL_I2S2_REGS->I2STXLT0;

    dmaConfig.srcAddr       = (Uint32)i2sDmaReadBufLeft;

    /* Open DMA ch0 for I2S left channel read */
    dmaLeftRxHandle = DMA_open(DMA_CHAN_L, &dmaObj0,&status);//DMA_CHAN_L = 4
    if (dmaLeftRxHandle == NULL)
    {
    	LOG_printf(&trace,"DMA_open CH4 Failed \n");
        dmaLeftRxHandle = NULL;
    }

    /* Configure DMA channel */
    status = DMA_config(dmaLeftRxHandle, &dmaConfig);
    if (status != CSL_SOK)
    {
    	LOG_printf(&trace,"DMA_config CH4 Failed \n");
        dmaLeftRxHandle = NULL;
    }

//	I2S_transEnable(hI2s, TRUE);

    /* Configure DMA ch1 for I2S right channel read */
    dmaConfig.pingPongMode = CSL_DMA_PING_PONG_ENABLE;
    dmaConfig.autoMode     = CSL_DMA_AUTORELOAD_ENABLE;
    dmaConfig.burstLen     = CSL_DMA_TXBURST_1WORD;
    dmaConfig.trigger      = CSL_DMA_EVENT_TRIGGER;

    dmaConfig.dmaEvt        = CSL_DMA_EVT_I2S2_TX;

    dmaConfig.dmaInt       = CSL_DMA_INTERRUPT_ENABLE;
    dmaConfig.chanDir      = CSL_DMA_WRITE;
    dmaConfig.trfType      = CSL_DMA_TRANSFER_IO_MEMORY;
    dmaConfig.dataLen      = NUM_SAMP_PER_MS*NUM_MS_PER_FRAME*2;  // two frames

    dmaConfig.destAddr     = (Uint32)&CSL_I2S2_REGS->I2STXRT0;

    dmaConfig.srcAddr      = (Uint32)i2sDmaReadBufRight;

    /* Open DMA ch0 for I2S right channel read */
    dmaRightRxHandle = DMA_open(DMA_CHAN_R, &dmaObj1,&status);//DMA_CHAN_R = 5
    if (dmaRightRxHandle == NULL)
    {
    	LOG_printf(&trace,"DMA_open CH1 Failed \n");
        dmaRightRxHandle = NULL;
    }

    /* Configure DMA channel */
    status = DMA_config(dmaRightRxHandle, &dmaConfig);
    if (status != CSL_SOK)
    {
    	LOG_printf(&trace,"DMA_config CH1 Failed \n");
        dmaRightRxHandle = NULL;
    }

//	I2S_transEnable(hI2s, TRUE);

    /* Start left Rx DMA */
    status = DMA_start(dmaLeftRxHandle);
    if (status != CSL_SOK)
    {
    	LOG_printf(&trace,"I2S Dma Left Failed!!\n");
        return (status);
    }

    /* Start right Rx DMA */
    status = DMA_start(dmaRightRxHandle);
    if (status != CSL_SOK)
    {
    	LOG_printf(&trace,"I2S Dma Right Failed!!\n");
        return (status);
    }

    // Enable DMA interrupt
    IRQ_enable(DMA_EVENT); // ����,�����޷�����DMA�ж�

    /* Enable I2S */
    I2S_transEnable(hI2s, TRUE);

    return CSL_SOK;
}