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

📄 audio_test.c

📁 ADI blackfin processor BF527 Ezkti test driver
💻 C
字号:
/*****************************************************************************
**																			**
**	 Name: 	BF537 C Talkthrough I2S										**
**																			**
******************************************************************************

(C) Copyright 2004 - Analog Devices, Inc.  All rights reserved.

File Name:	Main.c

Date Modified:	12/14/04	GO		Rev 1.0
				01/11/05	TL		Rev 1.1 Updated to work on Rev 1.1 of the
				                    ADSP-BF537 EZ-Kit

Software:       VisualDSP++4.0

Hardware:	ADSP-BF537 EZ-KIT Board Rev 1.1
			Users of ADSP-BF537 EZ-KIT Board Rev 1.0 must change the SPORT to
			generate internal clock and frame sync

Purpose:	This program sets up the ADSP-BF537 to reset the ADC and DAC.
			The data to/from the DAC/ADC are transfered over SPORT0 in I2S mode.

Program Parameters:


******************************************************************************/
#include <sysreg.h>
#include <ccblkfn.h>
#include <signal.h>
#include <complex.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <filter.h>
#include <vector.h>

#include "post_common.h"
#include "Pll.h"
#include "Timer_ISR.h"


//--------------------------------------------------------------------------//
// function prototypes
//--------------------------------------------------------------------------//
EX_INTERRUPT_HANDLER(Sport0_RX_ISR);


//--------------------------------------------------------------------------//
// Symbolic constants														//
//--------------------------------------------------------------------------//
// names for registers in AD1854/AD187 converters
#define INTERNAL_ADC_L0			0
#define INTERNAL_ADC_R0			1
#define INTERNAL_DAC_L0			0
#define INTERNAL_DAC_R0			1
#define SLEN_24		0x0017// SPORT0 word length
#define FLOW_1		0x1000// DMA flow mode



//--------------------------------------------------------------------------//
// Test paramaters														//
//--------------------------------------------------------------------------//
#define MAX_SAMPLES	 				256
#define REQUIRED_SAMPLES			((MAX_SAMPLES) * 250)
#define DESIRED_FREQ 				((float)3000.0)
#define SAMPLE_RATE 				((float)48000.0)
#define AMPLITUDE					((float)8388607)
#define PI							((float)3.141592765309)

#define ACCEPTABLE_DEVIATION_PCT	((float)0.015)
#define ACCEPTABLE_DEVIATION		(DESIRED_FREQ  * ACCEPTABLE_DEVIATION_PCT)
#define MAX_DESIRED_FREQ			(DESIRED_FREQ + ACCEPTABLE_DEVIATION)
#define MIN_DESIRED_FREQ			(DESIRED_FREQ - ACCEPTABLE_DEVIATION)
#define MIN_SIGNAL_STRENGTH			(float)35.0
#define MAX_NOISE_THRESHOLD			(float)10.0




//--------------------------------------------------------------------------//
// Variables used for test
//--------------------------------------------------------------------------//
volatile int  g_iSampleIndex = 1;
volatile int  g_iSampleCount = 0;
short g_fSineWaveIn_Left[MAX_SAMPLES];
short g_fSineWaveIn_Right[MAX_SAMPLES];
int iTxBuffer1[2];// SPORT0 DMA transmit buffer
int iRxBuffer1[2];// SPORT0 DMA receive buffer



//--------------------------------------------------------------------------//
// Function:	Init_Sport0													//
//																			//
//  Description:	Configure PORTF flags to control ADC and DAC RESETs
//--------------------------------------------------------------------------//
void Init_Flags(void)
{

}


//--------------------------------------------------------------------------//
// Function:	Init_Sport0													//
//																			//
// Description:	This function Resets the ADC and DAC.
//--------------------------------------------------------------------------//
void Audio_Reset(void)
{

	int i;

	// set PORTF clear register
    //*pPORTFIO_CLEAR = PF12;

	// give some time for reset to take affect
    for(i = 0; i< 0xf00;i++){};

    // set port f set register
    *pPORTFIO_SET = PF12;

}

//--------------------------------------------------------------------------//
// Function:	Init_Sport0													//
//																			//
// Description:	Configure Sport0 for I2S mode, to transmit/receive data 	//
//				to/from the ADC/DAC.Configure Sport for external clocks and //
//				frame syncs.												//
//--------------------------------------------------------------------------//
void Init_Sport0(void)
{
	// Sport0 receive configuration
	// External CLK, External Frame sync, MSB first, Active Low
	// 24-bit data, Secondary side enable, Stereo frame sync enable
// Users of ADSP-BF537 EZ-KIT Board Rev 1.0 must enable the internal clock and frame sync
	*pSPORT0_RCR1 = RFSR | LRFS | RCKFE;
	*pSPORT0_RCR2 = SLEN_24 | RSFSE;

	// Sport0 transmit configuration
	// External CLK, External Frame sync, MSB first, Active Low
	// 24-bit data, Secondary side enable, Stereo frame sync enable
// Users of ADSP-BF537 EZ-KIT Board Rev 1.0 must enable the internal clock and frame sync
	*pSPORT0_TCR1 = TFSR | LTFS | TCKFE;
	*pSPORT0_TCR2 = SLEN_24 | TSFSE;
}

//--------------------------------------------------------------------------//
// Function:	Init_DMA													//
//																			//
// Description:	Initialize DMA3 in autobuffer mode to receive and DMA4 in	//
//				autobuffer mode to transmit									//
//--------------------------------------------------------------------------//
void Init_DMA(void)
{
	// Configure DMA3
	// 32-bit transfers, Interrupt on completion, Autobuffer mode
	*pDMA3_CONFIG = WNR | WDSIZE_32 | DI_EN | FLOW_1;
	// Start address of data buffer
	*pDMA3_START_ADDR = iRxBuffer1;
	// DMA loop count
	*pDMA3_X_COUNT = 2;
	// DMA loop address increment
	*pDMA3_X_MODIFY = 4;


	// Configure DMA4
	// 32-bit transfers, Autobuffer mode
	*pDMA4_CONFIG = WDSIZE_32 | FLOW_1;
	// Start address of data buffer
	*pDMA4_START_ADDR = iTxBuffer1;
	// DMA loop count
	*pDMA4_X_COUNT = 2;
	// DMA loop address increment
	*pDMA4_X_MODIFY = 4;

}

//--------------------------------------------------------------------------//
// Function:	Enable_DMA_Sport											//
//																			//
// Description:	Enable DMA3, DMA4, Sport0 TX and Sport0 RX					//
//--------------------------------------------------------------------------//
void Enable_DMA_Sport0(void)
{
	// enable DMAs
	*pDMA4_CONFIG	= (*pDMA4_CONFIG | DMAEN);
	*pDMA3_CONFIG	= (*pDMA3_CONFIG | DMAEN);

	// enable Sport0 TX and RX
	*pSPORT0_TCR1 	= (*pSPORT0_TCR1 | TSPEN);
	*pSPORT0_RCR1 	= (*pSPORT0_RCR1 | RSPEN);
}

//--------------------------------------------------------------------------//
// Function:	Init_Interrupts												//
//																			//
// Description:	Initialize Interrupt for Sport0 RX							//
//--------------------------------------------------------------------------//
void Init_Interrupts(void)
{
	// Set Sport0 RX (DMA3) interrupt priority to 2 = IVG9
	*pSIC_IAR0 &= 0xff0fffff;
	*pSIC_IAR0 |= 0x00200000;

	// assign ISRs to interrupt vectors
	// Sport0 RX ISR -> IVG 9
	register_handler(ik_ivg9, Sport0_RX_ISR);

	// enable Sport0 RX interrupt
	*pSIC_IMASK |= IRQ_DMA3;
}







//--------------------------------------------------------------------------//
// Function:	Sport0_RX_ISR												//
//																			//
// Description: This ISR is executed after a complete frame of input data 	//
//				has been received. The new samples are stored in 			//
//				iChannel0LeftIn and iChannel0RightIn.  Then the function 	//
//				Process_Data() is called in which user code can be executed.//
//				After that the processed values are copied from the 		//
//				variables iChannel0LeftOut and iChannel0RightOut into the  	//
//				DMA transmit buffer.										//
//--------------------------------------------------------------------------//
EX_INTERRUPT_HANDLER(Sport0_RX_ISR)
{
	int iChannelX;
	float fIn;

	// confirm interrupt handling
	*pDMA3_IRQ_STATUS = 0x0001;

	// right channel in
	iChannelX = iRxBuffer1[INTERNAL_ADC_L0];
	iChannelX = (iChannelX >> 8);
//	if( iChannelX & 0x00800000)
//	{	// negative sign extend
//		iChannelX |= 0xFF000000;
//	}
	g_fSineWaveIn_Right[g_iSampleIndex] = (short)iChannelX;


	iChannelX = iRxBuffer1[INTERNAL_ADC_R0];
	iChannelX = (iChannelX >> 8);
//	if( iChannelX & 0x00008000)
//	{	// negative sign extend
//		iChannelX |= 0xFFFF0000;
//	}
	g_fSineWaveIn_Left[ g_iSampleIndex ] = (short)iChannelX;

	// send data to output
	iChannelX = (int)(AMPLITUDE * sin( (2.0 * PI * DESIRED_FREQ * ( ((float)(g_iSampleCount+1)) / SAMPLE_RATE))) );

	iTxBuffer1[INTERNAL_DAC_L0] = iChannelX;
	iTxBuffer1[INTERNAL_DAC_R0] = iChannelX;

	g_iSampleIndex++;	// only increment the index when both channels have been sent.

	if( g_iSampleIndex > MAX_SAMPLES-1 )
		g_iSampleIndex = 0;


	g_iSampleCount++;
}

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

	// FFT magnitude (includes Nyquist)
	fract16 mag[(MAX_SAMPLES / 2) + 1];

	// twiddle factors
	complex_fract16 w[MAX_SAMPLES];

	complex_fract16 out[MAX_SAMPLES];
	fract16 in[MAX_SAMPLES];
	int BlockExponent;

	// create the input sinewave 3000 hz at 48000 sample rate amplitude is 24-bit's max
	for( nSampleNumber = 0; nSampleNumber < MAX_SAMPLES; nSampleNumber++ )
	{
		in[nSampleNumber] = (short)psRealIn[nSampleNumber];
	}

	// generate twiddle factors
	twidfftrad2_fr16(w, MAX_SAMPLES);

	// perform real fft
	rfft_fr16( in, out, w, 1, MAX_SAMPLES, &BlockExponent, 1 );

	// 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
	for( nSampleNumber = 0; nSampleNumber <= (MAX_SAMPLES / 2); nSampleNumber++ )
	{
		mag[nSampleNumber] = cabs_fr16(out[nSampleNumber]);
	}
	nHighestFreqIndex = vecmaxloc_fr16(mag,(MAX_SAMPLES / 2) + 1);

	// multiply the index of the array of the highest value with the sample rate value
	fSampledFrequency = nHighestFreqIndex * (SAMPLE_RATE / MAX_SAMPLES);

	// make sure frequency is within acceptable ranges
	if( (fSampledFrequency < MAX_DESIRED_FREQ) && (fSampledFrequency > MIN_DESIRED_FREQ) )
	{
			// check the signal strength
	    float fDB = 10 * log10( (float)mag[nHighestFreqIndex] );
	    if( fDB < MIN_SIGNAL_STRENGTH )
	    {
	    	return 0;	// test failed
	    }

	    float fSigStrength = 0.0;
	    for( i = 1; i <= (MAX_SAMPLES / 2); i++)
	    {
	        fSigStrength = 10 * log10( (float)mag[i] );
	        if( (fSigStrength > MAX_NOISE_THRESHOLD) && (i != nHighestFreqIndex) )
	        	return 0; 	// test failed
	    }

		return 1;
	}

	return 0;	// test failed
}


int TEST_AUDIO(void)
{
	int nResult = 0;

	g_iSampleCount = 0;

	Init_Timers();
	Init_Timer_Interrupts();


	Init_Flags();
	Audio_Reset();
	Init_Sport0();
	Init_DMA();
	Init_Interrupts();
	Enable_DMA_Sport0();


	unsigned int nTimer = SetTimeout(0x50000);
	if( ((unsigned int)-1) != nTimer )
	{
	    // once the required number of samples has been collected,
	    // process the signal.
		do{
			asm("nop;");
		}while( (g_iSampleCount < REQUIRED_SAMPLES)  && (!IsTimedout(nTimer)) );
	}

	ClearTimeout(nTimer);

    // turn off interrupts so that the data is stable.
    interrupt(ik_ivg9, SIG_IGN);
	// disable Sport0 RX interrupt
	*pSIC_IMASK &= (~IRQ_DMA3);


    // test the right channel
    nResult  = Test_Channel(g_fSineWaveIn_Right);

    if( 1 == nResult  ) // Right channel was OK, test left channel
    {
		nResult = Test_Channel(g_fSineWaveIn_Left);
    }

    // turn off any of the interrupts used


    return nResult;
}

//--------------------------------------------------------------------------//
// Function:	main														//
//																			//
// Description:	After calling a few initalization routines, main() just 	//
//				waits in a loop forever.  The code to process the incoming  //
//				data can be placed in the function Process_Data() in the 	//
//				file "Process_Data.c".										//
//--------------------------------------------------------------------------//
#ifdef _STANDALONE_ // use this to run standalone tests
void main(void)
{
	int n;

   	TEST_AUDIO();
}
#endif //_STANDALONE_

⌨️ 快捷键说明

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