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.

Dropping samples from DMA buffer when UART-module initialized in interrupt mode on ezdspC5535



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

  • Hello again everybody!

    I've taken further steps in my troubleshooting and stripped the UART code to the bare minimum, initializing it in polled mode instead of interrupt mode. If I run the function dma_init() after uart_init() the program works as intended but if I run try to use any UART function the same problem with dropping samples persists.

    Help please!