⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test_ez_audio.c

📁 ADSP 地层驱动
💻 C
字号:
/*********************************************************************************

Copyright(c) 2005 Analog Devices, Inc. All Rights Reserved. 

This software is proprietary and confidential.  By using this software you agree
to the terms of the associated Analog Devices License Agreement.  


Description:
			This is the source code for the Blackfin EZ-Audio Power On Self Test 
			(POST).
			
*********************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sysreg.h>
#include <ccblkfn.h>
#include <math.h>
#include <filter.h>
#include <signal.h>
#include <string.h>
#include "Test_EZ_Audio.h"
#include "AD1938_Test.h"
#include "ADAV801_Test.h"


//////////////////////////////////////////////////////////////////////////////
// 							Common defines
//////////////////////////////////////////////////////////////////////////////
typedef struct CODEC_NAMES_tag
{
	char *pName;
	int iChannel;
	
}CODEC_NAMES;



//////////////////////////////////////////////////////////////////////////////
// 							Globals
//////////////////////////////////////////////////////////////////////////////
volatile float 			g_fDesired_Freq 		= ((float)5000.0);
volatile float 			g_fSamplesPerSin 		= 1;
volatile int 			g_iBufferSampleSize		= 1;

volatile unsigned char 	g_ucAudioInEnable 		= 0;
volatile int 			g_iSampleIndex 			= 0;
volatile long  			g_lSampleCount 			= 0;
unsigned int 			g_uiOutputSampleIndex 	= 0;

volatile long 			g_lAudioInputBufferL[AUDIO_IN_BUF_LEN];
volatile long 			g_lAudioInputBufferR[AUDIO_IN_BUF_LEN];
volatile long 			g_lAudioOutputBufferRef[AUDIO_IN_BUF_LEN];


//--------------------------------------------------------------------------//
// Function:	int TEST_1938(void)
//																			//
// Description: Perform frequency and amplitude test on AD1938
//--------------------------------------------------------------------------//
int TEST_1938(void)
{
	int i;
	int j;
	int iResult = 1;
	int nIndex;
	int nFreqIndex;
	const float fFreq[NUM_TEST_FREQUENCIES] = {440.0, 1000.0, 2000.0, 3000.0, 5000.0, 8000.0, 16000};
	const CODEC_NAMES g_cstADC_Names[] = 
	{ 
		{"ADC Channel1", INTERNAL_ADC_L1},
		{"ADC Channel2", INTERNAL_ADC_L2}, 
		{"ADC Channel3", INTERNAL_ADC_L3},
		{"ADC Channel4", INTERNAL_ADC_L4} };
	
	const CODEC_NAMES g_cstDAC_Names[] = 
	{ 
		{"DAC Channel1", INTERNAL_DAC_L1},
		{"DAC Channel3", INTERNAL_DAC_L3}, 
		{"DAC Channel5", INTERNAL_DAC_L5},
		{"DAC Channel7", INTERNAL_DAC_L7},
		{"DAC Channel2", INTERNAL_DAC_L2},
		{"DAC Channel4", INTERNAL_DAC_L4}, 
		{"DAC Channel6", INTERNAL_DAC_L6},
		{"DAC Channel8", INTERNAL_DAC_L8} };
		
	*pFIO_DIR		= 0x0003;
	*pFIO_FLAG_S	= 0x0003;
	
	
	Init1938_B();
	Init1938_A();

	Init_Sport1();
	Init_Sport1_DMA();
	Init_Sport1_Interrupts();
	Enable_Sport1_DMA();
		
	
	// check each channel individually
	for( nIndex = 0; nIndex < 4; nIndex++ )
	//for( nIndex = 0; nIndex < 1; nIndex++ )
	{
		for(nFreqIndex = 0; nFreqIndex < NUM_TEST_FREQUENCIES; nFreqIndex++)
		//for(nFreqIndex = 0; nFreqIndex < 1; nFreqIndex++)
		{
			g_fDesired_Freq = fFreq[nFreqIndex];
			g_fSamplesPerSin = SAMPLES_PER_SIN;
						
			g_iBufferSampleSize = (AUDIO_IN_BUF_LEN / g_fSamplesPerSin); // convert to int (for rounding) 
			g_iBufferSampleSize = (g_iBufferSampleSize * (float)(g_fSamplesPerSin));
			
			
			// generate the sin table
			memset((void*)g_lAudioOutputBufferRef, 0x00, (sizeof(long) * AUDIO_IN_BUF_LEN) );
			for( j = 0; j < (int)g_fSamplesPerSin*2; j++ )
			{
				g_lAudioOutputBufferRef[j] = (long)(AMPLITUDE * sin( (2.0 * PI * g_fDesired_Freq * ( ((float)(j)) / SAMPLE_RATE_T))));
			}
			

			memset((void*)g_lAudioInputBufferL, 0x00, (sizeof(long) * AUDIO_IN_BUF_LEN) );
			memset((void*)g_lAudioInputBufferR, 0x00, (sizeof(long) * AUDIO_IN_BUF_LEN) );
			g_lADC_TestChannel = g_cstADC_Names[nIndex].iChannel;
			g_lDAC_TestChannel = g_cstDAC_Names[nIndex].iChannel;
	
			
			// test channel
		   	#ifdef _DEBUG
		   		printf("\nTesting %s + %s at: %fhz\n", g_cstADC_Names[nIndex].pName, g_cstDAC_Names[nIndex].pName, g_fDesired_Freq );
		   		printf("\tleft\n");
		   	#endif
			
			g_iSampleIndex = 0;
			g_lSampleCount = 0;
			g_ucAudioInEnable = 1;
			
			do{
				asm("nop;");
			}while( (g_lSampleCount < REQUIRED_SAMPLES) );
	
			g_ucAudioInEnable = 0;
			
			iResult = Test_Channel( (long*)g_lAudioInputBufferL);
			if( iResult )
			{	// test right channel
			   	#ifdef _DEBUG
		   			printf("\tright\n");
			   	#endif
				iResult = Test_Channel( (long*)g_lAudioInputBufferR);
			}
			
			if( 0 == iResult )
			{
				break;
			}
		}

		if( 0 == iResult )
		{
			break;
		}
	}

	
	
	// check each channel individually
	for( nIndex = 0; nIndex < 4; nIndex++ )
	//for( nIndex = 0; nIndex < 1; nIndex++ )
	{
		for(nFreqIndex = 0; nFreqIndex < NUM_TEST_FREQUENCIES; nFreqIndex++)
		//for(nFreqIndex = 0; nFreqIndex < 1; nFreqIndex++)
		{
			g_fDesired_Freq = fFreq[nFreqIndex];
			g_fSamplesPerSin = SAMPLES_PER_SIN;
						
			g_iBufferSampleSize = (AUDIO_IN_BUF_LEN / g_fSamplesPerSin); // convert to int (for rounding) 
			g_iBufferSampleSize = (g_iBufferSampleSize * (float)(g_fSamplesPerSin));
			
			
			// generate the sin table
			memset((void*)g_lAudioOutputBufferRef, 0x00, (sizeof(long) * AUDIO_IN_BUF_LEN) );
			for( j = 0; j < (int)g_fSamplesPerSin*2; j++ )
			{
				g_lAudioOutputBufferRef[j] = (long)(AMPLITUDE * sin( (2.0 * PI * g_fDesired_Freq * ( ((float)(j)) / SAMPLE_RATE_T))));
			}
			

			memset((void*)g_lAudioInputBufferL, 0x00, (sizeof(long) * AUDIO_IN_BUF_LEN) );
			memset((void*)g_lAudioInputBufferR, 0x00, (sizeof(long) * AUDIO_IN_BUF_LEN) );
			g_lADC_TestChannel = g_cstADC_Names[nIndex].iChannel;
			g_lDAC_TestChannel = g_cstDAC_Names[nIndex+4].iChannel;
	
			
			// test channel
		   	#ifdef _DEBUG
		   		printf("\nTesting %s + %s at: %fhz\n", g_cstADC_Names[nIndex].pName, g_cstDAC_Names[nIndex+4].pName, g_fDesired_Freq );
		   		printf("\tleft\n");
		   	#endif
			
			g_iSampleIndex = 0;
			g_lSampleCount = 0;
			g_ucAudioInEnable = 1;
			
			do{
				asm("nop;");
			}while( (g_lSampleCount < REQUIRED_SAMPLES) );
	
			g_ucAudioInEnable = 0;
			
			iResult = Test_Channel( (long*)g_lAudioInputBufferL);
			if( iResult )
			{	// test right channel
			   	#ifdef _DEBUG
		   			printf("\tright\n");
			   	#endif
				iResult = Test_Channel( (long*)g_lAudioInputBufferR);
			}
			
			if( 0 == iResult )
			{
				break;
			}
		}

		if( 0 == iResult )
		{
			break;
		}
	}
	
	// disable DMAs
	*pDMA4_CONFIG	= 0;
	*pDMA3_CONFIG	= 0;
		
	// disable Sport1 TX and RX
	*pSPORT1_TCR1 	= 0;
	*pSPORT1_RCR1 	= 0;

    // turn off interrupts so that the data is stable.
    register_handler(ik_ivg9, EX_INT_DEFAULT);
	// disable Sport0 RX interrupt
	*pSIC_IMASK &= (~0x00000800);
		
	return iResult;
	
}

//--------------------------------------------------------------------------//
// Function:	int TEST_ADAV801(void)
//																			//
// Description: Perform frequency and amplitude test on ADAV801
//--------------------------------------------------------------------------//
int TEST_ADAV801(void)
{
	int i;
	int j;
	int iResult = 1;
//	int nIndex;
	int nFreqIndex;
	const float fFreq[NUM_TEST_FREQUENCIES] = {440.0, 1000.0, 2000.0, 3000.0, 5000.0, 8000.0, 16000};

	InitADAV801();

	Init_Sport0();
	Init_Sport0_DMA();
	Init_Sport0_Interrupts();
	Enable_Sport0_DMA();
	
	// check each channel individually
//	for( nIndex = 0; nIndex < 4; nIndex++ )
//	{
		for(nFreqIndex = 0; nFreqIndex < NUM_TEST_FREQUENCIES; nFreqIndex++)
		{
			g_fDesired_Freq = fFreq[nFreqIndex];
			g_fSamplesPerSin = SAMPLES_PER_SIN;
						
			g_iBufferSampleSize = (AUDIO_IN_BUF_LEN / g_fSamplesPerSin); // convert to int (for rounding) 
			g_iBufferSampleSize = (g_iBufferSampleSize * (float)(g_fSamplesPerSin));
			
			
			// generate the sin table
			memset((void*)g_lAudioOutputBufferRef, 0x00, (sizeof(long) * AUDIO_IN_BUF_LEN) );
			for( j = 0; j < (int)g_fSamplesPerSin*2; j++ )
			{
				g_lAudioOutputBufferRef[j] = (long)((AMPLITUDE/0x100) * sin( (2.0 * PI * g_fDesired_Freq * ( ((float)(j)) / SAMPLE_RATE_T))));
			}
			

			memset((void*)g_lAudioInputBufferL, 0x00, (sizeof(long) * AUDIO_IN_BUF_LEN) );
			memset((void*)g_lAudioInputBufferR, 0x00, (sizeof(long) * AUDIO_IN_BUF_LEN) );
	
			// test channel
		   	#ifdef _DEBUG
		   		printf("\nTesting %s at: %fhz\n", "SPDIF RX/TX", g_fDesired_Freq );
		   		printf("\tleft\n");
		   	#endif
			
			g_iSampleIndex = 0;
			g_lSampleCount = 0;
			g_ucAudioInEnable = 1;
			
			do{
				asm("nop;");
			}while( (g_lSampleCount < REQUIRED_SAMPLES/200) );
				
			g_ucAudioInEnable = 0;
			

			iResult = Test_Channel( (long*)g_lAudioInputBufferL);
			if( iResult )
			{	// test right channel
			   	#ifdef _DEBUG
		   			printf("\tright\n");
			   	#endif
				iResult = Test_Channel( (long*)g_lAudioInputBufferR);
			}
			
			if( 0 == iResult )
			{
				break;
			}
		}

//		if( 0 == iResult )
//		{
//			break;
//		}
//	}

	// disable DMAs
	*pDMA1_CONFIG	= 0;
	*pDMA2_CONFIG	= 0;
		
	// disable Sport1 TX and RX
	*pSPORT0_TCR1 	= 0;
	*pSPORT0_RCR1 	= 0;
	
    // turn off interrupts so that the data is stable.
    register_handler(ik_ivg9, EX_INT_DEFAULT);
	// disable Sport0 RX interrupt
	*pSIC_IMASK &= (~0x00000200);
	
	
	return iResult;
	
}


//--------------------------------------------------------------------------//
// Function:	Test_Channel												//
//																			//
// Description: Takes a buffer of data and determines if the frequecny  
//				and amplitude are within acceptable limits
//--------------------------------------------------------------------------//
int Test_Channel(long* psRealIn)
{
	int bSuccess = 0;
	short nSampleNumber;
	short iTempFreq;
	short nHighestFreqIndex;
	float fSampledFrequency;

	// twiddle factors
	complex_fract16 w[AUDIO_IN_BUF_LEN];
	
	complex_fract16 out[AUDIO_IN_BUF_LEN];
	complex_fract16 t[AUDIO_IN_BUF_LEN];  
	fract16 in[AUDIO_IN_BUF_LEN];  
	
	// create the input sinewave 3000 hz at 48000 sample rate amplitude is 24-bit's max
	for( nSampleNumber = 0; nSampleNumber < g_iBufferSampleSize; nSampleNumber++ )
	{
		in[nSampleNumber] = (psRealIn[nSampleNumber] >> 16 );
	}
    
	// generate twiddle factors
	twidfftrad2_fr16(w, AUDIO_IN_BUF_LEN);

	// perform real fft
	rfft_fr16( in, t, out, w, 1, AUDIO_IN_BUF_LEN, 0, 0 );


	// expect one of the index's of the array to contain a
	// 'spike' or high value such that frequency == index * (SAMPLE_RATE/MAX_SAMPLES) == 3000
	iTempFreq = (short)sqrt(out[0].re*out[0].re+out[0].im*out[0].im);
	for( nSampleNumber = 1; nSampleNumber < (g_iBufferSampleSize / 2); nSampleNumber++ )
	{
		if( ((short)sqrt(out[nSampleNumber].re*out[nSampleNumber].re+out[nSampleNumber].im*out[nSampleNumber].im)) > iTempFreq )
		{
			iTempFreq = (short)sqrt(out[nSampleNumber].re*out[nSampleNumber].re+out[nSampleNumber].im*out[nSampleNumber].im);
			nHighestFreqIndex = nSampleNumber;
		}
	}
	
   // multiply the index of the array of the highest value with the sample rate value
   fSampledFrequency = nHighestFreqIndex * (SAMPLE_RATE_T / g_iBufferSampleSize);
   
   #ifdef _DEBUG
   printf("\t\t-Sampled Freqyency: Min: %fhz Sampled:%fhz Max:%fhz \n", MIN_DESIRED_FREQ, fSampledFrequency, MAX_DESIRED_FREQ );
   #endif
      
   // make sure frequency is within acceptable ranges
   if( (fSampledFrequency < MAX_DESIRED_FREQ) && (fSampledFrequency > MIN_DESIRED_FREQ) )
   {
   		// check the signal streangth
		float fDB = 10 * log10( (float)iTempFreq );

	   	#ifdef _DEBUG
	   		printf("\t\t-Sampled Amplitude: Min:%fdb Sampled:%fdb \n", MIN_SIGNAL_STRENGTH, fDB  );
	   	#endif

	   	if( fDB < MIN_SIGNAL_STRENGTH )
	    {
	    	bSuccess = 0;
	    }
	    else
	    {	// passed
	    	bSuccess = 1;
	    }
   }
   
   	#ifdef _DEBUG
   		if( bSuccess )
   		{
   			printf("\t\t-PASSED\n");
   		}
   		else
   		{
   			fprintf(stderr, "\t\t-FAILED\n");
   		}
   	#endif
   
	return bSuccess;	// test failed
}







#ifdef _STANDALONE_
void main(void)
{
	// init the pll
	volatile int test=0;

	sysreg_write(reg_SYSCFG, 0x32);		//Initialize System Configuration Register

	*pSIC_IWR = 0x1;
	*pPLL_CTL = 0x2C00;
	ssync();
	idle();
	
	
	*pFIO_DIR		= 0x000B;
	*pFIO_FLAG_S	= 0x0003;
	*pFIO_FLAG_C	= 0x0008;
	

	// for now, do the ADAV801 test as a one time test.
	if( 0 == TEST_ADAV801() )
	{
		asm("emuexcpt;");
	}
	
	do{
		if( 0 == TEST_1938() )
		{
			asm("emuexcpt;");
		}
	}while(1);

}
#endif //_STANDALONE_



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -