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

📄 ac97.org.c

📁 三星s3c2460开发板完整功能测试代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*******************************************************************************

	File Name: AC97.c

	Description: S3C2460 AC97 Controller Function Test Code
	Version: 0.0
       History:
             0.0: 2004. 06. 17, First draft by Yoh-Han Lee
       	    - This S3C2460 AC97 test code works with WM9710 AC97 CODEC on the SMDK2460. 
		    -	AC97 PCM-In in DMA or interrupt mode is supported.
                  - AC97 PCM-Out in DMA or interrupt mode is supported.
		    - Volume up/down is available, when codec plays PCM data.
                  - AC97 power down mode test is supported.	
                  - AC97 reset timing check is supported.
                  - Variable ADC/DAC operation is supported. 

	S3C2460 AC97 test code is derived from following S3C2440A AC97 test code.
	...     

	File Name: AC97.c
	Description: S3C2440A AC97 Controller Function Test Code
   	Version: 0.2 
   	History:
             0.0: First draft
             0.1: 2003. 12. 22, Following test codes were modified by Yoh-Han Lee           
                   - AC97 PCM Out in DMA mode
                   - AC97 PCM In in DMA mode
             0.2: 2004. 02. 12, Programmed and tested by Yoh-Han Lee
                   - Volume up/down and Mute on/off are available, when codec plays PCM data.
		     - AC97 power down mode test is supported.	
                   - AC97 reset timing check is added.
                   - Variable ADC/DAC Selection is supported. 
                   - AC97 PCM Out in the interrupt mode is supported. Thanks to Y. M. Lee.
                   - AC97 PCM In using interrupt mode is supported.
                   - AC97 MIC In using interrupt or DMA is added.
                   
                  
********************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "option.h"
#include "2460addr.h"
#include "2460lib.h"
#include "2460slib.h"

#include "ac97.h"

#define AC97_REC_LEN 0xfffff*4	//Max value of DMA Transfer Counter (20bit) = 0xfffff, Date Size=Word (4bytes)

#define DOWN_BUF _NONCACHE_STARTADDRESS
#define PCM_OUT_TRIGGER 8
#define PCM_IN_TRIGGER 8
#define AC97_PCM_OUT_THRESHOLD (1<<18)
#define AC97_PCM_IN_THRESHOLD (1<<17)
#define AC97_MIC_IN_THRESHOLD (1<<16)

unsigned int save_AC97_rGPACON, save_AC97_rGPADAT, save_AC97_rGPAUP;
unsigned int AC97_size, AC97_fs;
unsigned int Output_Volume,Input_Volume;
unsigned int *Rec_AC97_BUF, *Play_AC97_BUF, *End_AC97_BUF;
static int delayLoopCount;
static int intCount; 
volatile static int	timer_exit=0;

volatile short PCM_Out_INT_Exit = 0;
volatile short PCM_In_INT_Exit =0;

unsigned char *AC97_BUF,*AC97_temp;
unsigned char Volume_Control;

char AC97_Rec_Done = 0;
char Codec_Ready_Irq;
char AC97_mute = 1;
char Codec_Ready = 1;

void AC97_Port_Init(void);
void AC97_Port_Return(void);
void AC97_Init(void);

void AC97_CodecInit_PCMOut(unsigned short AC97_fs);
void AC97_CodecInit_PCMIn(unsigned short AC97_fs);
void AC97_CodecInit_MICIn(unsigned short AC97_fs);
void AC97_CodecInit_PD(void);
void AC97_CodecExit_PCMOut(void);
void AC97_CodecExit_PCMIn(unsigned short DACs_off);
void AC97_CodecExit_MICIn(unsigned short DACs_off);

void AC97_PCMout_DMA1(unsigned int PCM_Size);
void AC97_PCMout_INT(unsigned int PCM_Size);
void AC97_PCMin_DMA2(unsigned int PCM_Size);
void AC97_PCMin_INT(unsigned int PCM_Size);
void AC97_MICin_DMA3(unsigned int MIC_Size);
void AC97_MICin_INT(unsigned int PCM_Size);
 
void PCM_In_Volume( unsigned char Up_Down_Volume);
void PCM_Out_Volume( unsigned char Up_Down_Volume);

float delay_func(unsigned short num_delay); 
 
void AC97_Controller_State(void);
unsigned short AC97_Select_SamplingRate(void);
unsigned short AC97_Codec_Cmd(unsigned char CMD_Read, unsigned char CMD_Offset, unsigned short CMD_Data);

static void __irq DMA1_Play_Done(void);
static void __irq DMA2_Rec_Done(void);
static void __irq DMA3_Rec_Done(void);
static void __irq RxInt(void);
//static void __irq Muting(void);
void __irq AC97_Codec_Ready(void);
void __irq Irq_AC97_PCMout(void);
void __irq Irq_AC97_PCMin(void);
void __irq Irq_AC97_MICin(void);

static void __irq IsrWatchdog(void);

void * func_ac97_test[][2]=
{	
	//AC97 Function Test Item
	(void *)Powerdown_Test_AC97,	"AC97 Power Down   ",  
	(void *)PCM_In_Out_Test_AC97,	"Record Sound via LineIn and Play it  ",   
	(void *)MICin_Test_AC97,		"Record Voice via MIC and Play it      ",    
	(void *)Reset_Test_AC97,		"AC97 Reset Timing Check ",
	0,0
};

void AC97_Test(void)
{
	int i;

	AC97_Port_Init();
	
	while(1)
	{
		i=0;
		printf("\n\n==================== AC97 Function Test ====================\n\n");
		while(1)
		{   //display menu
			printf("%2d:%s",i,func_ac97_test[i][1]);
			i++;
			if((int)(func_ac97_test[i][0])==0)
			{
				printf("\n");
				break;
			}
			if((i%2)==0)
			printf("\n");
		}
		printf("\n============================================================");
		printf("\nSelect #Item or Press enter key to exit:");
		i = GetIntNum();
			
		
		if(i==-1) break;		// return.	
		if(i>=0 && (i<(sizeof(func_ac97_test)/8)) )	// select and execute...
			( (void (*)(void)) (func_ac97_test[i][0]) )();
	}
	
	rAC_GLBCTRL = 0;
}

void PCM_In_Out_Test_AC97(void)
{
	int i;
	unsigned int Sampling_Rate;
	
	AC97_Rec_Done = 0;

	AC97_Port_Init();

	Sampling_Rate = AC97_Select_SamplingRate();
	  
	AC97_Init();	

	if(Codec_Ready)
	{
		printf("\nSelect PCM In/Out Operation Mode\n");
		printf("0: Interrupt, 1: DMA\n");
		i = GetIntNum();

       	AC97_CodecInit_PCMIn(Sampling_Rate);

		switch(i)
       	{
   			case 0:
	       		AC97_PCMin_INT(AC97_REC_LEN);

				//Play Recorded Data
		    	AC97_CodecInit_PCMOut(Sampling_Rate);
				AC97_PCMout_INT(AC97_REC_LEN);
       		break;

			case 1:
         		AC97_PCMin_DMA2(AC97_REC_LEN);
			
         		//Play Recorded Data
	    		AC97_CodecInit_PCMOut(Sampling_Rate);
	   			AC97_PCMout_DMA1(AC97_REC_LEN);
	   		break;
  			
			default:
				AC97_PCMin_DMA2(AC97_REC_LEN);
         		
	    		//Play Recorded Data
	    		AC97_CodecInit_PCMOut(Sampling_Rate);
	   			AC97_PCMout_DMA1(AC97_REC_LEN);
   			break;
		}
		AC97_CodecExit_PCMIn(1);
	}	

	Codec_Ready =1;
	AC97_mute = 1;

	PCM_Out_INT_Exit = 0;
	PCM_In_INT_Exit = 0;

	AC97_Port_Return();
}

void MICin_Test_AC97(void)
{
	unsigned short i, Sampling_Rate;
	
	AC97_Rec_Done = 0;
	
	AC97_Port_Init();
	Delay(1000);

	Sampling_Rate = AC97_Select_SamplingRate();
       
	AC97_Init();	

	if(Codec_Ready)
	{
		printf("\nSelect MIC In Operation Mode\n");
		printf("0: Interrupt, 1: DMA\n");
		i = GetIntNum();		
		
       	AC97_CodecInit_MICIn(Sampling_Rate);

		switch(i)
       	{
			case 0:
				AC97_MICin_INT(AC97_REC_LEN/2);

				//Play Recorded Data
	    		AC97_CodecInit_PCMOut(Sampling_Rate);
	   			AC97_PCMout_DMA1(AC97_REC_LEN/2);	
			break;

			case 1:
				AC97_MICin_DMA3(AC97_REC_LEN/2);

         		//Play Recorded Data
	    		AC97_CodecInit_PCMOut(Sampling_Rate);
	   			AC97_PCMout_DMA1(AC97_REC_LEN/2);
			break;	

			default:
				AC97_MICin_DMA3(AC97_REC_LEN/2);

         		//Play Recorded Data
	    		AC97_CodecInit_PCMOut(Sampling_Rate);
	   			AC97_PCMout_DMA1(AC97_REC_LEN/2);	
			break;
 		}	
		
  		AC97_CodecExit_MICIn(1);
	}

	Codec_Ready =1;
	AC97_mute = 1;
	PCM_In_INT_Exit = 0;

	AC97_Port_Return();
}

void Powerdown_Test_AC97(void)
{
	int i;
	float temp;

	AC97_Port_Init();
	Delay(1000);

	temp=delay_func(0xff);
	printf("\n%f\n",temp);

	AC97_Init();

	if(Codec_Ready)
	{
	  	AC97_CodecInit_PD();
	 
	 	//Normal
	 	printf("\nNormal\n");
	 	AC97_Controller_State();
	 	printf("AC97 Codec Powerdown Ctrl/Stat Reg. Value (at 0x26): 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));
	 
	 	//ADCs off
	 	printf("\n=>ADCs off PR0\n");
	 	AC97_Codec_Cmd(0,0x26,(1<<8));
	 	AC97_Controller_State();
	 	printf("AC97 Codec Powerdown Ctrl/Stat Reg. Value (at 0x26): 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));
	 
	 	//DACs off
	 	printf("\n=>DACs off PR1\n");
	 	AC97_Codec_Cmd(0,0x26,(1<<8)|(1<<9));
	 	AC97_Controller_State();
	 	printf("AC97 Codec Powerdown Ctrl/Stat Reg. Value (at 0x26): 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));	
	 
	 	//Analog off
	 	printf("\n=>Analog off PR2\n");
	 	AC97_Codec_Cmd(0,0x26,(1<<8)|(1<<9)|(1<<10));
	 	AC97_Controller_State();
	 	printf("AC97 Codec Powerdown Ctrl/Stat Reg. Value (at 0x26): 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));	
	 
	 	//Digital I/F off
	 	printf("\n=>Digital I/F off PR4\n");
	 	AC97_Codec_Cmd(0,0x26,(1<<8)|(1<<9)|(1<<10)|(1<<12));
	 	AC97_Controller_State();
	 	//printf("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));	
	 
	 	//Shut off AC-Link
	 	printf("\n=>Shut off AC-Link\n");
	 	rAC_GLBCTRL &= ~(1<<2);
	 	AC97_Controller_State();
	 	//printf("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));	
	 	  	
	 	while(1)
	 	{
	 		printf("\nPress enter key for Warm Reset");
	 		i = GetIntNum();
	 		if(i==-1) break;	
	 	}
	 
	 	//Warm Reset
	 	printf("\n=>Warm Reset\n");
	 	rAC_GLBCTRL = (1<<1);
	 	AC97_Controller_State();
	 	rAC_GLBCTRL &= ~(1<<1);
	 	
	 	rAC_GLBCTRL |= (1<<2);
	 	AC97_Controller_State();
	 	rAC_GLBCTRL |= (1<<3);
	 	printf("AC97 Codec Powerdown Ctrl/Stat Reg. Value (at 0x26): 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));	
	 
	 	//Cold Reset
	 	printf("\n=>Cold Reset\n");
	 	rAC_GLBCTRL |= (1<<0);
	 	AC97_Controller_State();
	 	rAC_GLBCTRL &= ~(1<<0);
	 	
	 	rAC_GLBCTRL |= (1<<2);
	 	AC97_Controller_State();
	 	rAC_GLBCTRL |= (1<<3);
	 	AC97_Controller_State();
	 	printf("AC97 Codec Powerdown Ctrl/Stat Reg. Value (at 0x26): 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));	
	}

	Codec_Ready =1;
	AC97_Port_Return();
}

void Reset_Test_AC97(void)
{
	int i;
	
	AC97_Port_Init();
	Delay(1000);

	AC97_Init();

	if(Codec_Ready)
	{
	 	AC97_CodecInit_PD();

		//Normal
		printf("\nNormal\n");
		AC97_Controller_State();
		printf("AC97 Codec Powerdown Ctrl/Stat Reg. Value (at 0x26): 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));	
	
		//ADCs off
		printf("\n=>ADCs off PR0\n");
		AC97_Codec_Cmd(0,0x26,(1<<8));
		AC97_Controller_State();
		printf("AC97 Codec Powerdown Ctrl/Stat Reg. Value (at 0x26): 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));	
		
		//DACs off
		printf("\n=>DACs off PR1\n");
		AC97_Codec_Cmd(0,0x26,(1<<8)|(1<<9));
		AC97_Controller_State();
		printf("AC97 Codec Powerdown Ctrl/Stat Reg. Value (at 0x26): 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));	

		//Analog off
		printf("\n=>Analog off PR2\n");
		AC97_Codec_Cmd(0,0x26,(1<<8)|(1<<9)|(1<<10));
		AC97_Controller_State();
		printf("AC97 Codec Powerdown Ctrl/Stat Reg. Value (at 0x26): 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));	
		
		//Digital I/F off
		printf("\n=>Digital I/F off PR4\n");
		AC97_Codec_Cmd(0,0x26,(1<<8)|(1<<9)|(1<<10)|(1<<12));
		AC97_Controller_State();
		
		//Shut off AC-Link
		printf("\n=>Shut off AC-Link\n");
		rAC_GLBCTRL &= ~(1<<2);
		//AC97_Codec_Cmd(0,0x26,(1<<8)|(1<<9)|(1<<10)|(1<<12));
		AC97_Controller_State();

		//Warm Reset Timing Check
		printf("\nWarm Reset Timing Check...");
		printf("\n	Probe SYNC and BIT_CLK.");
		printf("\n	Trigger SYNC Rising Edge.");
		
		while(1)
		{
			printf("\nPress enter key for Warm Reset Timing Check...");
			i = GetIntNum();
			if(i==-1) break;	
		}

		printf("\n=>Warm Reset\n");
		rAC_GLBCTRL = (1<<1);
		AC97_Controller_State();
		rAC_GLBCTRL &= ~(1<<1);

		rAC_GLBCTRL |= (1<<2);
		AC97_Controller_State();
		rAC_GLBCTRL |= (1<<3);
		//AC97_Controller_State();
		printf("AC97 Codec Powerdown Ctrl/Stat Reg. Value (at 0x26): 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));	
		//AC97_Controller_State();

		printf("\nPress any key.\n");
		getchar();
		
		//Cold Reset Timing Check
		printf("\nCold Reset Timing Check...");
		printf("\n	Probe RESET#, BIT_CLK and SDATA_IN.");
		printf("\n	Trigger RESET# Rising Edge.");


		while(1)
		{
			printf("\nPress enter key for Cold Reset Timing Check...");
			i = GetIntNum();
			if(i==-1) break;	
		}

		rAC_GLBCTRL = 0x1;	
		Delay(1000);			
		rAC_GLBCTRL = 0x0;	
		Delay(1000);		

		printf("\nPress any key to exit.\n");
		getchar();
	}

	Codec_Ready =1;
	AC97_Port_Return();	
}

/* Functional Sub-Routines */

⌨️ 快捷键说明

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