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.
/* * 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; }