Hello everybody,
For a project we've tried to merge some code that feeds audio from input J3 through the codec and into memory via DMA, and then from there out to the output J4, with code that initializes the UART-module and sends a character through loopback and receives that character through an interrupt service routine. The problem is that as soon as we try to send a character we start to drop samples and the audio starts to get choppy. If we comment out the line of code in main that sends the character through the loopback, the audio is fine. Any ideas whats causing trouble?
// MAIN.C
#include "stdio.h"
#include "ezdsp5535.h"
#include "ezdsp5535_i2s.h"
#include "ezdsp5535_i2c.h"
#include "aic_dma.h"
#include "csl_uart.h"
//#include "dsplib.h"
extern Int16 aic3204_init( );
extern Int16 aic3204_close( );
extern CSL_UartHandle hUart;
extern CSL_Status status;
extern CSL_Status dma_init(void);
/*
*
* main( )
*
*/
int rec_data;
int * ptr;
int data_ready;
int enable_lms = 0;
extern int pp;
int pp0=0;
int pp1=0;
/* Buffers for L/R audio input/receive */
extern Uint16 dmaPingDstBufLR[CSL_DMA_BUFFER_SIZE];
extern Uint16 dmaPongDstBufLR[CSL_DMA_BUFFER_SIZE];
extern Uint16 dmaPingDstBufRR[CSL_DMA_BUFFER_SIZE];
extern Uint16 dmaPongDstBufRR[CSL_DMA_BUFFER_SIZE];
/* Declaration of the L/R audio output/send buffers */
extern Uint16 dmaPingSrcBufLS[CSL_DMA_BUFFER_SIZE];
extern Uint16 dmaPongSrcBufLS[CSL_DMA_BUFFER_SIZE];
extern Uint16 dmaPingSrcBufRS[CSL_DMA_BUFFER_SIZE];
extern Uint16 dmaPongSrcBufRS[CSL_DMA_BUFFER_SIZE];
char tx = 'A';
//int ppREF = 0;
void main( void )
{
int index;
/* Initialize BSL */
EZDSP5535_init( );
printf( "\nInitializing AIC3204...\n");
/* Initialize I2C */
EZDSP5535_I2C_init( );
/* Call aic init */
aic3204_init( );
/* Call dma init */
dma_init( );
/* Call uart init */
uart_init( );
status = UART_fputc(hUart, tx, 2); // Test tx
while (1) // eternal loop
{
if (data_ready>0)
{
data_ready--;
if (pp == 0){
// PING EVENT
for(index = 0; index < CSL_DMA_BUFFER_SIZE; index++)
{
dmaPingSrcBufLS[index] = dmaPingDstBufLR[index]; // Feed through L/R Audio
dmaPingSrcBufRS[index] = dmaPingDstBufRR[index];
};
}
else // PONG EVENT
{
for(index = 0; index < CSL_DMA_BUFFER_SIZE; index++)
{
dmaPongSrcBufLS[index] = dmaPongDstBufLR[index]; // Feed through L/R Audio
dmaPongSrcBufRS[index] = dmaPongDstBufRR[index];
};
}
}
}
}
/*
This code defines dma transfer between aic3204 and ping pong buffers in memory for both left and right
channels using 4 separate dma channels.
It is assumed the aic3204 is configured elsewhere and serial data can be sent and retrived from the I2S2 bus.
*/
#include "csl_dma.h"
#include "csl_intc.h"
#include "aic_dma.h"
#include <stdio.h>
/* Reference the start of the interrupt vector table */
extern void VECSTART(void);
/* prototype declaration for ISR function */
extern int isr_count,isr_count_ping,isr_count_pong;
//extern int lms(int x, int y);
/**
* \brief DMA Interrupt Service routine
* \param none
* \return none
*/
interrupt void dma_isr(void);
/* Buffers for L/R audio input/receive */
#pragma DATA_ALIGN (dmaPingDstBufLR, 4)
Uint16 dmaPingDstBufLR[CSL_DMA_BUFFER_SIZE];
#pragma DATA_ALIGN (dmaPongDstBufLR, 4)
Uint16 dmaPongDstBufLR[CSL_DMA_BUFFER_SIZE];
#pragma DATA_ALIGN (dmaPingDstBufRR, 4)
Uint16 dmaPingDstBufRR[CSL_DMA_BUFFER_SIZE];
#pragma DATA_ALIGN (dmaPongDstBufRR, 4)
Uint16 dmaPongDstBufRR[CSL_DMA_BUFFER_SIZE];
/* Declaration of the L/R audio output/send buffers */
#pragma DATA_ALIGN (dmaPingSrcBufLS, 4)
Uint16 dmaPingSrcBufLS[CSL_DMA_BUFFER_SIZE];
#pragma DATA_ALIGN (dmaPongSrcBufLS, 4)
Uint16 dmaPongSrcBufLS[CSL_DMA_BUFFER_SIZE];
#pragma DATA_ALIGN (dmaPingSrcBufRS, 4)
Uint16 dmaPingSrcBufRS[CSL_DMA_BUFFER_SIZE];
#pragma DATA_ALIGN (dmaPongSrcBufRS, 4)
Uint16 dmaPongSrcBufRS[CSL_DMA_BUFFER_SIZE];
CSL_DMA_Handle dmaHandleLS,dmaHandleRS,dmaHandleLR,dmaHandleRR;
CSL_DMA_Config dmaConfigLS,dmaConfigRS,dmaConfigLR,dmaConfigRR;
CSL_DMA_Config getdmaConfig;
int pingLR,pingRR,pingLS,pingRS;
int tcr2 =0;
extern CSL_Status status;
int pp =0;
/**
* \brief DMA Ping-Pong Mode transfers from DRAM to/from aic3204
* \param none
* \return none
*/
int dma_init(void)
{
CSL_DMA_ChannelObj dmaObjLS,dmaObjRS,dmaObjLR,dmaObjRR;
/* Left Receive */
dmaConfigLR.pingPongMode = CSL_DMA_PING_PONG_ENABLE;
dmaConfigLR.autoMode = CSL_DMA_AUTORELOAD_ENABLE;
dmaConfigLR.burstLen = CSL_DMA_TXBURST_1WORD;
dmaConfigLR.trigger = CSL_DMA_EVENT_TRIGGER;
dmaConfigLR.dmaEvt = CSL_DMA_EVT_I2S2_RX ; // or CSL_DMA_EVT_I2S2_TX
dmaConfigLR.dmaInt = CSL_DMA_INTERRUPT_DISABLE; // Use this?
dmaConfigLR.chanDir = CSL_DMA_READ; // CSL_DMA_WRITE
dmaConfigLR.trfType = CSL_DMA_TRANSFER_IO_MEMORY;
dmaConfigLR.dataLen = CSL_DMA_BUFFER_SIZE * 4;
dmaConfigLR.srcAddr = 0x2A28; // I2SRXLT0
dmaConfigLR.destAddr = (Uint32)dmaPingDstBufLR; //
/* Right Receive */
dmaConfigRR.pingPongMode = CSL_DMA_PING_PONG_ENABLE;
dmaConfigRR.autoMode = CSL_DMA_AUTORELOAD_ENABLE;
dmaConfigRR.burstLen = CSL_DMA_TXBURST_1WORD;
dmaConfigRR.trigger = CSL_DMA_EVENT_TRIGGER;
dmaConfigRR.dmaEvt = CSL_DMA_EVT_I2S2_RX ; // or CSL_DMA_EVT_I2S2_TX
dmaConfigRR.dmaInt = CSL_DMA_INTERRUPT_ENABLE; // Use this?
dmaConfigRR.chanDir = CSL_DMA_READ; // CSL_DMA_WRITE
dmaConfigRR.trfType = CSL_DMA_TRANSFER_IO_MEMORY;
dmaConfigRR.dataLen = CSL_DMA_BUFFER_SIZE * 4;
dmaConfigRR.srcAddr = 0x2A2C; // I2SRXRT0
dmaConfigRR.destAddr = (Uint32)dmaPingDstBufRR; //
/* Left Send */
dmaConfigLS.pingPongMode = CSL_DMA_PING_PONG_ENABLE;
dmaConfigLS.autoMode = CSL_DMA_AUTORELOAD_ENABLE;
dmaConfigLS.burstLen = CSL_DMA_TXBURST_1WORD;
dmaConfigLS.trigger = CSL_DMA_EVENT_TRIGGER;
dmaConfigLS.dmaEvt = CSL_DMA_EVT_I2S2_TX ; // or CSL_DMA_EVT_I2S2_TX
dmaConfigLS.dmaInt = CSL_DMA_INTERRUPT_DISABLE; // Use this?
dmaConfigLS.chanDir = CSL_DMA_WRITE; // CSL_DMA_WRITE
dmaConfigLS.trfType = CSL_DMA_TRANSFER_IO_MEMORY;
dmaConfigLS.dataLen = CSL_DMA_BUFFER_SIZE * 4;
dmaConfigLS.destAddr = 0x2A08; // I2STXLT0
dmaConfigLS.srcAddr = (Uint32)dmaPingSrcBufLS; //
/* Right Send */
dmaConfigRS.pingPongMode = CSL_DMA_PING_PONG_ENABLE;
dmaConfigRS.autoMode = CSL_DMA_AUTORELOAD_ENABLE;
dmaConfigRS.burstLen = CSL_DMA_TXBURST_1WORD;
dmaConfigRS.trigger = CSL_DMA_EVENT_TRIGGER;
dmaConfigRS.dmaEvt = CSL_DMA_EVT_I2S2_TX ; // or CSL_DMA_EVT_I2S2_TX
dmaConfigRS.dmaInt = CSL_DMA_INTERRUPT_DISABLE; // Use this?
dmaConfigRS.chanDir = CSL_DMA_WRITE; // CSL_DMA_WRITE
dmaConfigRS.trfType = CSL_DMA_TRANSFER_IO_MEMORY;
dmaConfigRS.dataLen = CSL_DMA_BUFFER_SIZE * 4;
dmaConfigRS.destAddr = 0x2A0C; // I2STXRT0
dmaConfigRS.srcAddr = (Uint32)dmaPingSrcBufRS; //
IRQ_globalDisable();
IRQ_clearAll();
IRQ_disableAll();
IRQ_setVecs((Uint32)&VECSTART);
IRQ_clear(DMA_EVENT);
IRQ_plug (DMA_EVENT, &dma_isr);
IRQ_enable(DMA_EVENT);
IRQ_globalEnable();
status = DMA_init();
if (status != CSL_SOK)
{
printf("DMA_init() Failed \n");
}
dmaHandleLR = DMA_open((CSL_DMAChanNum) 4,&dmaObjLR, &status);
if (dmaHandleLR == NULL)
{
printf("DMA_open() Failed \n");
return 1;
}
dmaHandleRR = DMA_open((CSL_DMAChanNum) 5,&dmaObjRR, &status);
if (dmaHandleRR == NULL)
{
printf("DMA_open() Failed \n");
return 1;
}
dmaHandleLS = DMA_open((CSL_DMAChanNum) 6,&dmaObjLS, &status);
if (dmaHandleLS == NULL)
{
printf("DMA_open() Failed \n");
return 1;
}
dmaHandleRS = DMA_open((CSL_DMAChanNum) 7,&dmaObjRS, &status);
if (dmaHandleLS == NULL)
{
printf("DMA_open() Failed \n");
return 1;
}
status = DMA_config(dmaHandleLR, &dmaConfigLR);
status = DMA_config(dmaHandleRR, &dmaConfigRR);
status = DMA_config(dmaHandleLS, &dmaConfigLS);
status = DMA_config(dmaHandleRS, &dmaConfigRS);
if (status != CSL_SOK)
{
printf("DMA_config() Failed \n");
return 1;
}
status = DMA_start(dmaHandleLR);
status = DMA_start(dmaHandleRR);
status = DMA_start(dmaHandleLS);
status = DMA_start(dmaHandleRS);
if (status != CSL_SOK)
{
printf("DMA_start() Failed \n");
return 1;
}
printf("DMA_init() Done! \n");
return 0;
} // End of dma_init
int dma_stop(void){
status = DMA_close(dmaHandleLR);
status = DMA_close(dmaHandleRR);
status = DMA_close(dmaHandleLS);
status = DMA_close(dmaHandleRS);
if (status != CSL_SOK)
{
printf("DMA_close() Failed \n");
return(1);
}
status = DMA_reset(dmaHandleLR);
status = DMA_reset(dmaHandleRR);
status = DMA_reset(dmaHandleLS);
status = DMA_reset(dmaHandleRS);
if (status != CSL_SOK)
{
printf("DMA_reset() Failed \n");
return(2);
}
IRQ_clearAll();
IRQ_disableAll();
IRQ_globalDisable();
return(0);
} // dma_stop
/**
* \brief DMA Interrupt Service routine
* \param none
* \return none
*/
int ifrflags =0;
int lst_xfer_ping =0;
int lst_xfer_pong =0;
int bin_here1 = 0;
int bin_here2 = 0;
extern int data_ready;
interrupt void dma_isr(void) {
int ifrValue;
//printf("DMA IRQ\n");
ifrValue = CSL_SYSCTRL_REGS->DMAIFR;
ifrflags = ifrValue;
CSL_SYSCTRL_REGS->DMAIFR |= ifrValue; // Clear all flags by writing 1 to all active
CSL_FINST(CSL_CPU_REGS->IFR0, CPU_IFR0_DMA, DISABLED); // CLEAR DMA IFR IN CPU REG
if (ifrValue & CSL_SYS_DMAIFR_DMA1CH1IF_MASK) { // Channel 0 ready
pp = CSL_FEXT(dmaHandleRR->dmaRegs->DMACH1TCR2,
DMA_DMACH1TCR2_LTSTATUS); //LAST_XFER_BIT
data_ready++;
}
} // dma_isr
//UART_config.c
#include <stdio.h>
#include "cslr.h"
#include "cslr_cpu.h"
#include "csl_uart.h"
#include "csl_general.h"
#include "csl_uartAux.h"
#include "ezdsp5535.h"
CSL_UartSetup uartSetup =
{
/* Input clock freq in Hz */
8000000,
/* Baud rate */
9600,
/* Word length of 8 */
CSL_UART_WORD8,
/* To generate 1 stop bit */
0,
/* Disable the parity */
CSL_UART_DISABLE_PARITY,
/* Disable fifo */
/* Enable trigger 1 fifo */
CSL_UART_FIFO_DMA1_DISABLE_TRIG01,
/* Loop Back enable */
CSL_UART_LOOPBACK,
/* No auto flow control*/
CSL_UART_NO_AFE ,
/* No RTS */
CSL_UART_NO_RTS ,
};
CSL_UartObj uartObj; // UART objekt struktur
CSL_UartHandle hUart; // UART handtag
extern void VECSTART(void); // Interruptvectorns startadress
/* Fördefinitioner */
CSL_Status uart_init(void); //Sändarloop, initierar uart och skickar en buffer
CSL_Status FUART_init(CSL_UartObj * uartObj,Uint32 uartInstId,
CSL_UartOpmode opmode);
interrupt void uart_isr(void);
CSL_Status status;
char rx;
CSL_Status uart_init(void) {
CSL_UartIsrAddr isrAddr;
status = FUART_init(&uartObj,CSL_UART_INST_0,UART_INTERRUPT);
if(CSL_SOK != status) {
printf("UART_init failed error code %d\n",status);
return status;
}
else
{
printf("UART_init Successful\n");
}
hUart = (CSL_UartHandle)(&uartObj);
status = UART_setup(hUart,&uartSetup);
if(CSL_SOK != status)
{
printf("UART_setup failed error code %d\n",status);
return status;
}
else
{
printf("UART_setup Successful\n");
}
isrAddr.rbiAddr = uart_isr;
/* Disable interrupt */
IRQ_globalDisable();
/* Clear any pending interrupts */
IRQ_clearAll();
/* Disable all the interrupts */
IRQ_disableAll();
IRQ_setVecs((Uint32)(&VECSTART));
IRQ_clear(UART_EVENT);
/* Configuring Interrupt */
IRQ_plug (UART_EVENT, &uart_isr);
/* Enabling Interrupt */
IRQ_enable(UART_EVENT);
IRQ_enable(DMA_EVENT);
IRQ_globalEnable();
/* Set the UART callback function */
status = UART_setCallback(hUart,&isrAddr);
if(status != CSL_SOK)
{
printf("UART_setCallback Failed\n");
return(status);
}
/* Enable the UART Events */
status = UART_eventEnable(hUart, CSL_UART_RECVOR_REG_DATA_INTERRUPT);
if(status != CSL_SOK)
{
printf("UART_eventEnable Failed\n");
return(status);
}
return status;
}
interrupt void uart_isr() {
int ifrValue;
ifrValue = CSL_CPU_REGS->IFR0;
CSL_FINST(CSL_CPU_REGS->IFR0, CPU_IFR0_UART, DISABLED); // CLEAR UART IFR
status = UART_fgetc(hUart, &rx, 0);
//printf("UART ISR %c \n", rx);
}
CSL_Status FUART_init(CSL_UartObj * uartObj,Uint32 uartInstId,
CSL_UartOpmode opmode)
{
CSL_Status status = CSL_SOK;
if(NULL == uartObj)
{
return CSL_ESYS_INVPARAMS;
}
if(opmode == UART_OPMODE_OTHER)
{
return CSL_ESYS_INVPARAMS;
}
/* Set the base address */
switch ( uartInstId)
{
case CSL_UART_INST_0:
uartObj->insId = uartInstId;
uartObj->sysAddr = CSL_SYSCTRL_REGS;
uartObj->uartRegs = CSL_UART_REGS;
uartObj->opmode = opmode;
break;
default:
uartObj->insId = CSL_UART_INST_INVALID;
status = CSL_EUART_INVALID_INST_ID;
break;
}
if(CSL_UART_INST_INVALID != uartObj->insId)
{
/**Enable Master clock */
CSL_FINST(uartObj->sysAddr->PCGCR1,SYS_PCGCR1_SYSCLKDIS,ACTIVE);
/**Enable uart peripheral clock gating */
CSL_FINST(uartObj->sysAddr->PCGCR1,SYS_PCGCR1_UARTCG,ACTIVE);
/* changing parallel port mode to 5 - supports UART */
CSL_FINST(uartObj->sysAddr->EBSR,SYS_EBSR_PPMODE,MODE5);
/**Resetting UART module*/
//CSL_FINST(uartObj->sysAddr->PRCR, SYS_PRCR_PG4_RST,RST);
}
return status;
}