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.

dsplib taking lot of cpu cycles while working on c5515 dsp

Hi,

My application is the simple audio data acquisition system using the EVM5515. I have designed the timer ISR where I am acquiring the data from the codec. The timer designed at 12Khz frequency, I am using the DSPLIB for implementing the FIR filter when I am using these filters in timer ISR the frequency of the timer becomes 2Khz. That means the FIR filter is taking more timing to execute. I am attaching the timer.c and the linker file with this code. So please explain me am I missing something in the code. I am attaching timer.c and filter dop_filt.c code files. I have also attached the command file in zip format.

#include "dopp_filt.h"
//unsigned char filt_flg=0;
#if 1
//short test(DATA *r, DATA *rtest, short n, DATA maxerror);
void Filt_test_x(void)
{
	short eflag1= PASS;
	DATA  *dbptr = &db_x[0];
	unsigned char i;

    for (i = 0; i < NX; i++) r_x[i] = 0;       // clear output buffer (optional)
  //  if(filt_flg==0)
    for (i = 0; i < (NH+2); i++) db_x[i] = 0;    // clear delay buffer (a must)
//	filt_flg=1;
    // compute
    fir(x, h, r_x, dbptr, NX, NH);

    // test
//    eflag1 = test (r, rtest, NX, MAXERROR);

}
void Filt_test_y(void)
{
	short eflag1= PASS;
	DATA  *dbptr = &db_y[0];
	unsigned char i;

    for (i = 0; i < NX; i++) r_y[i] = 0;       // clear output buffer (optional)
  //  if(filt_flg==0)
    for (i = 0; i < (NH+2); i++) db_y[i] = 0;    // clear delay buffer (a must)
//	filt_flg=1;
    // compute
    fir(y, h, r_y, dbptr, NX, NH);

    // test
//    eflag1 = test (r, rtest, NX, MAXERROR);

}
void Filt_LP_x(void)
{
	short eflag1= PASS;
	DATA  *dbptr = &db_xLP[0];
	unsigned char i;

    for (i = 0; i < NX; i++) r_xLP[i] = 0;       // clear output buffer (optional)
  //  if(filt_flg==0)
    for (i = 0; i < (NH+2); i++) db_xLP[i] = 0;    // clear delay buffer (a must)
//	filt_flg=1;
    // compute
    fir(x_LP, h_LP, r_xLP, dbptr, NX, NH);

    // test
//    eflag1 = test (r, rtest, NX, MAXERROR);

}
void Filt_LP_y(void)
{
	short eflag1= PASS;
	DATA  *dbptr = &db_yLP[0];
	unsigned char i;

    for (i = 0; i < NX; i++) r_yLP[i] = 0;       // clear output buffer (optional)
  //  if(filt_flg==0)
    for (i = 0; i < (NH+2); i++) db_yLP[i] = 0;    // clear delay buffer (a must)
//	filt_flg=1;
    // compute
    fir(y_LP, h_LP, r_yLP, dbptr, NX, NH);

    // test
//    eflag1 = test (r, rtest, NX, MAXERROR);

}

#endif
#if 0
short test(DATA *r, DATA *rtest, short n, DATA maxerror)
{
short i;
short eflag = PASS;		// error flag or index into r vector where error
DATA elevel = 0;		// error level at failing eflag index location
DATA emax = 0;			// max error level detected across when NOERROR

for (i=0;i<n;i++)
    {
   elevel = ABSVAL(rtest[i] - r[i]);
    if ( elevel > maxerror)
       {
       eflag =i;	// if error --> eflag = index and emax= max error
       emax = elevel;	// if no error --> eflag = -1 and emax = max error
       break;
       }
    else
    if (elevel>emax) emax = elevel;
   }
			// Pass to Host: eflag and emax
return(eflag);
}
#endif
#if 0

#define Ntap 80

#define DCgain 32768
Int16 FIRCoef[Ntap] = { 
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
           -4,
           10,
           -7,
          -28,
          114,
         -190,
          -30,
         1153,
        -3784,
         7245,
        23809,
         7245,
        -3784,
         1153,
          -30,
         -190,
          114,
          -28,
           -7,
           10,
           -4,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0
    };

Int16 x[Ntap]={0}; 
Int16 fir(Int16 NewSample) 
{

    //input samples
    Int32 y=0;            //output sample
    int n;

    //shift the old samples
    for(n=Ntap-1; n>0; n--)
       x[n] = x[n-1];

    //Calculate the new output
    x[0] = NewSample;
    for(n=0; n<Ntap; n++)
        y += FIRCoef[n] * x[n];
    
    return y / DCgain;
}
#endif
0882.dopp_filt.h
/**********************************************************************
**+-----------------------------------------------------------------+**
**|                            ****                                 |**
**|                            ****                                 |**
**|                            ******o***                           |**
**|                      ********_///_****                          |**
**|                      ***** /_//_/ ****                          |**
**|                       ** ** (__/ ****                           |**
**|                           *********                             |**
**|                            ****                                 |**
**|                            ***                                  |**
**|                                                                 |**
**|   Copyright (c) 2006 - 2010    Texas Instruments Incorporated   |**
**|                        ALL RIGHTS RESERVED                      |**
**|                                                                 |**
**| Permission is hereby granted to licensees of Texas Instruments  |**
**| Incorporated (TI) products to use this computer program for     |**
**| the sole purpose of implementing a licensee product based       |**
**| on TI products.No other rights to reproduce, use, or            |**
**| disseminate this computer program, whether in part or in whole, |**
**| are granted.TI makes no representation or warranties with       |**
**| respect to the performance of this computer program, and        |**
**| specifically disclaims any responsibility for any damages,      |**
**| special or consequential,connected with the use of this program.|**
**|                                                                 |**
**+-----------------------------------------------------------------+**
**********************************************************************/
#include "data_types.h"
#include "timer.h"
#include "register_cpu.h"
#include "evm5515.h"


extern Int16 RX_Buff_Left[],RX_Buff_Right[],Buffer_Index;
extern Int8   Buffer_Full,Data_ready;

/////*Code added by Nitin*/
extern void Filt_test_y();
extern Int32 process_buf[];
extern void Filt_test_x();
extern void Filt_LP_x();
extern void Filt_LP_y();

extern Int16 x[];
extern Int16 y[];
extern Int16 x_LP[];
extern Int16 y_LP[];
extern Int16 r_x[];
extern Int16 r_y[];
extern Int16 r_xLP[];
extern Int16 r_yLP[];
Int8 Buff_full_flg=0;
Int16 RX_Right_filt[256],RX_Left_filt[256];

///*********************/

void Timer0Init(void)
{

	/*  Timer0 Initialization */
// timer interval 10msec
// prescale = 0 (devide by 2)
// 100/2 = 50MHz ==> 20 nsec
// 10msec/20nsec = 500000 (0x7A120)

	/* TIM0 EN | AutoReload disable | Prescale = 0(100/2 = 50MHz) ==> 20nsec */
	//*CPU_TIM0_CTRL = 0x8002; 	// autoReload
    *CPU_TIM0_CTRL = 0x8000; 	// disable autoReload

	//*CPU_TIM0_PLWR = 0xA120;  // for 100Hz
	//*CPU_TIM0_PHWR = 0x0007; 
	//*CPU_TIM0_PLWR = 0x0823; 	//for 24KHz timer 
	//*CPU_TIM0_PHWR = 0x0000;
//	*CPU_TIM0_PLWR = 0x1388; 	//for 10KHz timer 
//	*CPU_TIM0_PHWR = 0x0000; 
	*CPU_TIM0_PLWR = 0x1047; 	//for 12KHz timer 
	*CPU_TIM0_PHWR = 0x0000; 
	
	*CPU_TIM0_CLWR = 0x0000;
	*CPU_TIM0_CHWR = 0x0000;
	
	/*  Clearing timer Aggregation register*/
	*CPU_TIMINT_AGGR = 0x0007;

	/*  enable timer0 int flag*/
	*CPU_TIM0_IER = 0x0001;
}

void StartTimer0(void)
{
	/* Start the Timer 0*/
	*CPU_TIM0_CTRL = *CPU_TIM0_CTRL | 0x0001; 
}


interrupt void Timer_isr(void)
{
    Int16 DataL=0,DataR=0;
 //   EVM5515_LED_on(0);
   
    while((0x08 & I2S2_IR) == 0);   // Wait for receive interrupt to be pending
	DataL = I2S2_W0_MSW_R;  // 16 bit left channel received audio data
	DataR = I2S2_W1_MSW_R;  // 16 bit right channel received audio data
			/* Write Digital audio */
	while((0x20 & I2S2_IR) == 0);  // Wait for receive interrupt to be pending
	I2S2_W0_MSW_W = DataL;  // 16 bit left channel transmit audio data
	I2S2_W1_MSW_W = DataR ;  // 16 bit right channel transmit audio data
	
		x[Buffer_Index]= DataL;
		Filt_test_x();
		x_LP[Buffer_Index]=r_x[Buffer_Index];
//		x_LP[Buffer_Index]=	DataL;
		Filt_LP_x();
		RX_Left_filt[Buffer_Index]=r_xLP[Buffer_Index];
		
		
		y[Buffer_Index]= DataR;
		Filt_test_y();
		y_LP[Buffer_Index]=r_y[Buffer_Index];
	//	y_LP[Buffer_Index]=	DataR; 
		Filt_LP_y();
		RX_Right_filt[Buffer_Index]=r_yLP[Buffer_Index];
		
		RX_Buff_Left[Buffer_Index]=DataL;
		RX_Buff_Right[Buffer_Index++]=DataR;
		Buffer_Full = (Buffer_Index % 255);	
		if(Buffer_Full == 0)
		{
		 	Buffer_Index = 0;	 	
//		 	Buff_full_flg=1;
		}	


	Data_ready = 1;
		#endif
    // clear timer int flag
    IFR0 = IFR0&0x0010; 
    
	/*  clear timer0 int flag*/
	*CPU_TIM0_IER = 0x0001;
	    
	/*	Clear Timer0 bit in Timer Aggregate register*/
	*CPU_TIMINT_AGGR = *CPU_TIMINT_AGGR | 0x0001 ;	
    			
    StartTimer0();
}

4064.c5515.rar

  • Hello Nitin,

    I'm going to presume that you figured 12KHz with a nearly empty, or at least, less busy timer ISR.  Since you've added the FIR code to the Timer ISR, the amount of time between each trigger of this ISR has increased which explains the decrease in overall frequency.  What has not changed is the amount of time that you spend outside of the ISR.  This is what is controlled by the  CPU_TIM0_PLWR.  

    You can reduce *CPU_TIM0_PLWR but if you adjust the code inside the timer ISR, you;ll need to adjust this value again to maintain 12KHz.  One thing additionally catches my attention; you have polling statements inside of the ISR checking I2S flags.  Why not use an I2S interrupt?