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

📄 audio_test.c

📁 基于visual dsp++开发环境
💻 C
字号:
/*****************************************************************************
**																			**
**	 Name: 	Audio_test.c															**
**																			**
******************************************************************************

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

Project Name:	BF538F POST ATE

Date Modified:	01 Sept 2006

Software:		VisualDSP++ 4.5

Hardware:		ADSP-BF538F EZ-KIT Lite


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

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

#include <math.h>
#include <sysreg.h>
#include <ccblkfn.h>
#include <signal.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <filter.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)30.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 PORTD flags to control ADC and DAC RESETs
//--------------------------------------------------------------------------//
void Init_Flags(void)
{
	//set PORTD config register
   	*pPORTDIO_FER		= 0x0010;		// setup port for PD4 GPIO

	// set PORTD direction register
   	*pPORTDIO_DIR		= 0x0010;		// PD4 output

}


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

	int i;

	// set PORTF clear register
    *pPORTDIO_CLEAR		= 0x0010;

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

    // set port D set register
    *pPORTDIO_SET		= 0x0010;

}

//--------------------------------------------------------------------------//
// 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
	*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
	*pSPORT0_TCR1 = TFSR | LTFS | TCKFE;
	*pSPORT0_TCR2 = SLEN_24 | TSFSE;
}

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


	// Configure DMA4
	// 32-bit transfers, Autobuffer mode
	*pDMA2_CONFIG = WDSIZE_32 | FLOW_1;
	// Start address of data buffer
	*pDMA2_START_ADDR = iTxBuffer1;
	// DMA loop count
	*pDMA2_X_COUNT = 2;
	// DMA loop address increment
	*pDMA2_X_MODIFY = 4;

}

//--------------------------------------------------------------------------//
// Function:	Enable_DMA_Sport											//
//																			//
// Description:	Enable DMA1, DMA2, Sport0 TX and Sport0 RX					//
//--------------------------------------------------------------------------//
void Enable_DMA_Sport0(void)
{
	// enable DMAs
	*pDMA2_CONFIG	= (*pDMA2_CONFIG | DMAEN);
	*pDMA1_CONFIG	= (*pDMA1_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 (DMA1) interrupt priority to 2 = IVG9
	*pSIC_IAR1 &= 0xffffff0f;
	*pSIC_IAR1 |= 0x00000020;

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

	// enable Sport0 RX interrupt
	*pSIC_IMASK0 |= 0x00000200;
}


//--------------------------------------------------------------------------//
// 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
	*pDMA1_IRQ_STATUS = 0x0001;

	// right channel in
	iChannelX = iRxBuffer1[INTERNAL_ADC_L0];
	iChannelX = (iChannelX >> 8);

		g_fSineWaveIn_Right[g_iSampleIndex] = (short)iChannelX;


	iChannelX = iRxBuffer1[INTERNAL_ADC_R0];
	iChannelX = (iChannelX >> 8);

		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 frequecny is
//				and amplitude are within acceptable limits
//--------------------------------------------------------------------------//
int Test_Channel(short* psRealIn)
{
	short nSampleNumber;
	short iTempFreq;
	short nHighestFreqIndex;
	float fSampledFrequency;
	short iAllFreqs[MAX_SAMPLES/2];
	int i = 0;

	// twiddle factors
	complex_fract16 w[MAX_SAMPLES];

	complex_fract16 out[MAX_SAMPLES];
	complex_fract16 t[MAX_SAMPLES];
	fract16 in[MAX_SAMPLES];

	// 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, t, out, w, 1, MAX_SAMPLES, 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);
	iAllFreqs[0] = iTempFreq;
	for( nSampleNumber = 1; nSampleNumber < (MAX_SAMPLES / 2); nSampleNumber++ )
	{
	    iAllFreqs[nSampleNumber] = (short)sqrt(out[nSampleNumber].re*out[nSampleNumber].re+out[nSampleNumber].im*out[nSampleNumber].im);
		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 / MAX_SAMPLES);

	// 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 );
	    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)iAllFreqs[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 &= (~0x00000200);


    // 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 + -