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

📄 ac97.org.c

📁 三星s3c2460开发板完整功能测试代码
💻 C
📖 第 1 页 / 共 3 页
字号:
void AC97_Port_Init(void)
{
	//Push AC97 GPIO port configuration
	save_AC97_rGPADAT=rGPADAT;
	save_AC97_rGPACON=rGPACON; 
	save_AC97_rGPAUP=rGPAPU;

	//---------------------------------------------------------------------
	//PORT E GROUP
	//Ports  :  GPA4    		 GPA3             GPA2            GPA1                GPA0 
	//Signal :  AC97 SYNC   AC97 SDO     AC97 SDI      AC97 RESETn    AC97 BITCLK 
	//Binary :  11,               11,                11,                11,                   11    
	//---------------------------------------------------------------------
	rGPACON = rGPACON & ~(0x3ff) | 0x3ff;   //GPE[4:0]=> AC97 function
	rGPAPU  = rGPAPU  & ~(0x1f)  | 0x1f;    //The pull up function is disabled GPA[4:0] 1 1111
    	
	//For EINT0 Push Button 	
    	//rGPFUP   = ((rGPFUP   & ~(1<<0)) | (1<<0));     //GPF0
    	//rGPFCON  = ((rGPFCON  & ~(3<<0)) | (1<<1));     //GPF0=EINT0    
    	//rEXTINT0 = ((rEXTINT0 & ~(7<<0)) | (2<<0));     //EINT0=falling edge triggered 
	
}

void AC97_Port_Return(void)
{
	//Pop AC97 GPIO port configuration
	rGPACON=save_AC97_rGPACON; 
	rGPADAT=save_AC97_rGPADAT;
	rGPAPU=save_AC97_rGPAUP;
}

void AC97_Init(void)
{
	int i=0;
	unsigned char ch;

	printf("\nAC97 Initialization...\n");	
	
 	//Cold Reset 
	rAC_GLBCTRL = 0x1;	// controller and codec cold reset
	Delay(1000);			// delay for controller safety reset
	rAC_GLBCTRL = 0x0;	// controller and codec normal mode
	Delay(1000);		
	rAC_GLBCTRL = 0x1;							
	Delay(1000);									
	rAC_GLBCTRL = 0x0;						
	Delay(1000);	
	
	//AC-link On
	rAC_GLBCTRL = (1<<2);
	Delay(1000);	
	AC97_Controller_State();

	//Transfer data enable using AC-link
	rAC_GLBCTRL |= (1<<3);	// AC97 Data transfer active 
	Delay(1000);	
	AC97_Controller_State();
	printf("\nAC97-Link On...\n");
       
       //Codec Ready Check using Codec Ready Interrupt
       Codec_Ready_Irq =0;	
	pISR_PCM_AC97 = (unsigned)AC97_Codec_Ready;	

	ClearPending(BIT_PCM_AC97);	
	rSUBSRCPND=(BIT_SUB_AC97);

   	rINTMSK=~(BIT_PCM_AC97);			
   	rINTSUBMSK=~(BIT_SUB_AC97);

   	rAC_GLBCTRL |= 0x400000;
   	
	while(!Codec_Ready_Irq)
	{

	 	printf(".");
         	Delay(3000);
         	i++;
         	
         	if(i==20)
		break;
	 }

	printf("\n");

	if(i==20)
	{
		printf("\nAC97 codec is not ready.");
		printf("\nCheck on connection between S3C2460 and AC97 CODEC.\n");
		printf("\nBye. ");
		Codec_Ready = 0;
	}
}

void AC97_CodecInit_PD(void)
{
	printf("\nAC97 Codec Soft Reset\n");
	AC97_Codec_Cmd(0,0x00,0x683F);		//Codec Soft Reset : 16bit In/Out  (stac9766/67) 	
	printf("AC97 Codec 0x26 Reg.: 0x%x\n\n", AC97_Codec_Cmd(1,0x26,0x0000));		
}

void AC97_CodecInit_PCMIn( unsigned short AC97_fs)
{
	
	AC97_Codec_Cmd(0,0x00,0x683F);		//codec soft reset 	

	AC97_Codec_Cmd(0,0x26,(1<<9));		//all power on except DAC Block
	printf("\nAC97 Codec 0x26 Reg.: 0x%x\n\n", AC97_Codec_Cmd(1,0x26,0x0000));
	
	AC97_Codec_Cmd(0,0x2A,0x0001);		//variable rate enable	
	printf("VRA Enable(1)/Disable(0): 0x%x\n",(0x1&AC97_Codec_Cmd(1,0x2A,0x0001)));
	
	if(AC97_fs==48000){
	//ADC Sampling frequency 48kHz
	AC97_Codec_Cmd(0,0x32,0xbb80);	
	}
	else if(AC97_fs==44100){
	//ADC Sampling frequency 44.1kHz
	AC97_Codec_Cmd(0,0x32,0xac44);
	}
	else if(AC97_fs==22050){
	//ADC Sampling frequency 22.05kHz
	AC97_Codec_Cmd(0,0x32,0x5622);	 	
	}
	else if(AC97_fs==8000){
	//ADC Sampling frequency 8kHz
	AC97_Codec_Cmd(0,0x32,0x1F40);	 	
	}


	AC97_Codec_Cmd(0,0x10,0x1010);		//line in volume on
	AC97_Codec_Cmd(0,0x6e,0x0000);		//All Analog Mode, ADC Input select => left slot3, right slot4
	AC97_Codec_Cmd(0,0x1a,0x0505);		//record source select => Stereo Mix
	AC97_Codec_Cmd(0,0x1c,0x0909);		//record gain is initial
	AC97_Codec_Cmd(0,0x78,0x0001);		//ADC HPF Bypass
	AC97_Codec_Cmd(0,0x20,0x0000);		//General Reg.
	
	Input_Volume = 	AC97_Codec_Cmd(1,0x10,0x0000);	      //Line In volume	
	
}

void AC97_CodecInit_PCMOut( unsigned short AC97_fs)
{
	
	AC97_Codec_Cmd(0,0x00,0x683F);		//codec soft reset	

	AC97_Codec_Cmd(0,0x2A,0x0001);		//variable rate enable	
	//printf("\nVRA Enable(1)/Disable(0): 0x%x\n", (0x1&AC97_Codec_Cmd(1,0x2A,0x0001)));
	
	if(AC97_fs==48000){
	//DAC Sampling frequency 48kHz
	AC97_Codec_Cmd(0,0x2C,0xbb80);
	}
	else if(AC97_fs==44100){
	//DAC Sampling frequency 44.1kHz
	AC97_Codec_Cmd(0,0x2C,0xac44);
	}
	else if(AC97_fs==22050){
	//DAC Sampling frequency 22.05kHz
	AC97_Codec_Cmd(0,0x2C,0x5622);		
	}
	else if(AC97_fs==8000){
	//DAC Sampling frequency 22.05kHz
	AC97_Codec_Cmd(0,0x2C,0x1F40);		
	}

	AC97_Codec_Cmd(0,0x26, (1<<8));		// all power on except ADC blcok
	printf("AC97 Codec 0x26 Reg.: 0x%x\n\n", AC97_Codec_Cmd(1,0x26,0x0000));

	AC97_Codec_Cmd(0,0x18,0x0000);		// PCM out volume on
	AC97_Codec_Cmd(0,0x20,0x0000);		// general purpose
	AC97_Codec_Cmd(0,0x04,0x1A1A);		// Aux out(HP out) volume on
	
	Output_Volume = AC97_Codec_Cmd(1,0x04,0x00000);	//HP out volume 	
}

void AC97_CodecInit_MICIn(unsigned short AC97_fs)
{
	AC97_Codec_Cmd(0,0x00,0x683F);		//codec soft reset 	
	
	AC97_Codec_Cmd(0,0x2A,0x0001);		//variable rate enable	
	printf("VRA Enable(1)/Disable(0): 0x%x\n",(0x1&AC97_Codec_Cmd(1,0x2A,0x0001)));
	
	if(AC97_fs==48000){
		//ADC Sampling frequency 48kHz
		AC97_Codec_Cmd(0,0x32,0xbb80);	
	}
	else if(AC97_fs==44100){
		//ADC Sampling frequency 44.1kHz
		AC97_Codec_Cmd(0,0x32,0xac44);
	}
	else if(AC97_fs==22050){
		//ADC Sampling frequency 22.05kHz
		AC97_Codec_Cmd(0,0x32,0x5622);	 
	}
	else if(AC97_fs==8000){
		//ADC Sampling frequency 8kHz
		AC97_Codec_Cmd(0,0x32,0x1F40);	 
	}
	
	AC97_Codec_Cmd(0,0x26,(1<<9));		//all power on except DAC Block
	printf("\nAC97 Codec 0x26 Reg.: 0x%x\n\n", AC97_Codec_Cmd(1,0x26,0x0000));
	
	AC97_Codec_Cmd(0,0x20,0x0000);		//MIC1 Selected
	AC97_Codec_Cmd(0,0x6e,0x0024);		//ADC Input Slot => left slot6, right slot9, MIC GAIN VAL =1 
	AC97_Codec_Cmd(0,0x0e,0x0040);		//BOOSTEN =1
	AC97_Codec_Cmd(0,0x1a,0x0000);		//Left, Right => MIC
	AC97_Codec_Cmd(0,0x1c,0xff);		
	AC97_Codec_Cmd(0,0x78,0x0001);		//ADC HPF Bypass
	
	Input_Volume = 	AC97_Codec_Cmd(1,0x1c,0x0000);	      //Record Volume	
}

unsigned short AC97_Codec_Cmd(unsigned char CMD_Read, unsigned char CMD_Offset, unsigned short CMD_Data)
{ 
	 unsigned short Codec_Stat;

	if(CMD_Read == 0)
	{
		rAC_CODEC_CMD = (0<<23)|(CMD_Offset<<16)|(CMD_Data<<0);
		delay_func(2); //32 us delay 
	}
	else if (CMD_Read ==1) 
	{
		rAC_CODEC_CMD = (1<<23)|(CMD_Offset<<16)|(CMD_Data<<0);
		Delay(1000);

		Codec_Stat = (unsigned short)(rAC_CODEC_STAT & 0xFFFF);
		Delay(1000);
		return Codec_Stat;
	}
	else 
		return 0;
        
}

void PCM_In_Volume( unsigned char Up_Down_Volume)
{
	if( ( Up_Down_Volume == 'u') | (Up_Down_Volume == 'U') ) 
	{	
		if (Input_Volume == 0x0000) 
		{
			printf("Limit Volume Range!\n");
		} 
		else 
		{
			Input_Volume -= 0x0101;
			AC97_Codec_Cmd(0,0x10, Input_Volume);	// PCM In Volume Up	
			printf("PCM In Volume Level : 0x%x\n", Input_Volume);
		}
	}
				
	if ( ( Up_Down_Volume == 'd') | (Up_Down_Volume == 'D') ) 
	{	
		if (Input_Volume == 0x1F1F) 
		{
			printf("Limit Volume Range!\n");
		} 
		else 
		{
			Input_Volume += 0x0101;
			AC97_Codec_Cmd(0,0x10, Input_Volume);	// PCM In Volume Down
			printf("PCM In Volume Level : 0x%4x\n", Input_Volume);
		}
	}
}

void PCM_Out_Volume(unsigned char Up_Down_Volume)
{
	if( ( Up_Down_Volume == 'u') | (Up_Down_Volume == 'U') )
	{	
		if (Output_Volume == 0x0000) 
		{
			printf("\nLimit Volume Range!");
		} 
		else 
		{
			Output_Volume -= 0x0101;
			AC97_Codec_Cmd(0,0x04, Output_Volume);		// PCM out Volume Up
			printf("\nHeadphone Volume Level (In AC97 Codec 04h Reg.): 0x%x", Output_Volume);
		}
	}
				
	if ( ( Up_Down_Volume == 'd') | (Up_Down_Volume == 'D') ) 
	{	
		if (Output_Volume == 0x1F1F) 
		{
			printf("\nLimit Volume Range!");
		} 
		else 
		{
			Output_Volume += 0x0101;
			AC97_Codec_Cmd(0,0x04, Output_Volume);		// PCM out Volume Down
			printf("\nHeadphone Volume Level (In AC97 Codec 04h Reg.): 0x%x", Output_Volume);
		}
	}
}

void AC97_PCMout_DMA1(unsigned int PCM_Size)
{
	//pISR_EINT0= (unsigned)Muting;
	pISR_DMA_SBUS= (unsigned)DMA1_Play_Done;

	ClearPending(BIT_DMA_SBUS);	
	rSUBSRCPND=(BIT_SUB_DMA1);

	rINTMSK = ~(BIT_DMA_SBUS);
	rINTSUBMSK=~(BIT_SUB_DMA1);
	
	Play_AC97_BUF=(unsigned int *)(DOWN_BUF +0x30);
	
	//DMA Ch1 for PCMInitialize
	rDISRC1  = (int)Play_AC97_BUF;                 
	rDISRCC1 = (0<<1) + (0<<0);		//The source is in the system bus(AHB), Increment      
	rDIDST1  = ((unsigned int)0x45000018);  	//PCM Out Data Fifo    
	rDIDSTC1 = (1<<1) + (1<<0);           //The destination is in the peripheral bus(APB), Fixed  
	rDCON1   = (1<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(0<<22)+(2<<20)+(PCM_Size/4);
	rDMASKTRIG1 = (0<<2) + (1<<1) + (1<<0);          //No-stop[2], DMA1 channel On[1], No-sw trigger[0] 
	rDMAREQSEL1 = (6<<1) + (1<<0); 

	//AC97  Initialize
	printf("Connect head-phone plug into speaker-out socket on SMDK2460 and Press any key.\n");
	getchar();
	printf("Now Play...\n");
	printf("To Volume Up, Press the 'u' key.\n");
	printf("To Volume Down, Press the 'd' key.\n");
	printf("\nIf you want to exit, Press the 'x' key.\n");
	printf("Headphone Volume Register = 0x%x\n", Output_Volume);

	//Transfer data enable  using AC-Link
	rAC_GLBCTRL = 0x200C;
	//printf("\nWrite Value to AC_GLBCTRL Reg. =>0x200C\n");
	//printf("Read Value from AC_GLBCTRL Reg. =>0x%x\n", rAC_GLBCTRL);
	
	Delay(1000);    

  	while(1)
    {
		//printf("STAT3: 0x%x		CURR_TC: 0x%x		DCDST3: 0x%x\n", rDSTAT3&0x300000, rDSTAT3&0xfffff, rDCDST3);
		Volume_Control=getchar();

		if( (Volume_Control == 'x') | (Volume_Control == 'X')) 
			break;
    	
    	PCM_Out_Volume(Volume_Control);
   	}

	ClearPending(BIT_DMA_SBUS);	
	rSUBSRCPND=(BIT_SUB_DMA1);

	rDMASKTRIG1  = (1<<2);       //DMA1 stop

	rINTMSK |= (BIT_DMA_SBUS);
	rINTSUBMSK |=(BIT_SUB_DMA1);

	 //AC97 PCM In Channel Finish 
	 rAC_GLBCTRL &= ~(1<<13); //PCM Out Transfer Mode Off
	 printf("\nEnd of Play!\n");
}

void AC97_PCMout_INT(unsigned int PCM_Size)
{
	 //Record AC97_BUF initialize
       Rec_AC97_BUF   = (unsigned int *)(DOWN_BUF);
	Play_AC97_BUF = (Rec_AC97_BUF + 0x30);
	End_AC97_BUF = (Rec_AC97_BUF + 0x30 + PCM_Size/4);

	//IRQ Initialization
	pISR_PCM_AC97= (unsigned)Irq_AC97_PCMout;	

	printf("\nConnect head-phone plug into speaker-out socket on SMDK2460 and Press any key.\n");
	getchar();
	
	printf("\nNow Play...\n");
	printf("Headphone Volume Register = 0x%x\n", Output_Volume);

	ClearPending(BIT_PCM_AC97);	
	rSUBSRCPND=(BIT_SUB_AC97);

   	rINTMSK=~(BIT_PCM_AC97);			
   	rINTSUBMSK=~(BIT_SUB_AC97);

	rAC_GLBCTRL = 0x4100C;	//PCM Out channel threshold INT enable, PIO Mode On

	while(1)
	{
	       if(PCM_Out_INT_Exit == 1)
		break;	
	}

	rAC_GLBCTRL &= ~(1<<12); //PCM Out Transfer PIO Mode Off
		
	rINTSUBMSK|=(BIT_SUB_WDT|BIT_SUB_AC97);
	rINTMSK|=(BIT_PCM_AC97);

	printf("\nEnd of Play!\n");
}

void AC97_PCMin_DMA2(unsigned int PCM_Size)
{
	Rec_AC97_BUF   = (unsigned int *)(DOWN_BUF);  

	//IRQ Initialize	
	pISR_DMA_SBUS  = (unsigned)DMA2_Rec_Done;
	ClearPending(BIT_DMA_SBUS);	
	rSUBSRCPND=(BIT_SUB_DMA2);

	rINTMSK = ~(BIT_DMA_SBUS);
	rINTSUBMSK=~(BIT_SUB_DMA2);
      
       //DMA2 Initialize
	rDISRC2  = ((unsigned int)0x45000018);         //PCM Input Data FIFO
	rDISRCC2 = (1<<1) + (1<<0);          //APB, Fix  
       rDIDST2  = (int)Rec_AC97_BUF;   //Record AC97_BUF initializ
       rDIDSTC2 = (0<<1) + (0<<0);          //AHB, Increment
       rDCON2   = (1<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(1<<22)+(2<<20)+(PCM_Size/4);
	rDMAREQSEL2 = (7<<1) + (1<<0);
	
	printf("Are you ready to record sound via Line-in socket on SMDK2460?\n");
       printf("Press any key to start record.\n");
    	getchar();
   	printf("Recording...\n");

       rDMASKTRIG2 = (0<<2) + (1<<1) + 0;    //No-stop, DMA2 channel on, No-sw trigger
      
	// Transfer data enable  using AC-Link
       rAC_GLBCTRL = 0x80C;	// Transfer data enable  using AC-Link
	
	 
       //printf("\nWrite Value to AC_GLBCTRL Reg. =>0x80C\n");
	//printf("Read Value from AC_GLBCTRL Reg. =>0x%x\n", rAC_GLBCTRL);

	while(AC97_Rec_Done ==0)
       {
        	printf(".");
         	Delay(3000);
         	//printf("STAT2: 0x%x CURR_TC: 0x%x		DCDST2: 0x%x\n", rDSTAT2&0x300000, rDSTAT2&0xfffff, rDCDST2);
       }
    		
       AC97_Rec_Done = 0;

       ClearPending(BIT_DMA_SBUS);	
	rSUBSRCPND=(BIT_SUB_DMA2);
	
       rDMASKTRIG2 = (1<<2);     //DMA2 stop
     
       rINTMSK |= (BIT_DMA_SBUS);
	rINTSUBMSK |=(BIT_SUB_DMA2);

       //AC97 PCM In Channel Finish 
       rAC_GLBCTRL &= ~(1<<11); //PCM In Transfer Mode Off
   
  	Delay(1000); 

  	printf("\nEnd of Record!\n");
}

void AC97_PCMin_INT(unsigned int PCM_Size)
{
	//Record AC97_BUF initialize
       Rec_AC97_BUF   = (unsigned int *)(DOWN_BUF);
	Play_AC97_BUF = Rec_AC97_BUF + 0x30;
	End_AC97_BUF = (Rec_AC97_BUF + 0x30 + PCM_Size/4);

	//IRQ Initialization
	pISR_PCM_AC97= (unsigned)Irq_AC97_PCMin;	

	printf("Are you ready to record sound via Line-in socket on SMDK2460?\n");
       printf("Press any key to start record.\n");

⌨️ 快捷键说明

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