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

📄 ac97.c

📁 三星 s3c6400测试代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	 	AC97_CodecCmd(WRITE,0x26, 0x4f00);		// Enable PR5(Internal Clock, AC-link I/F)
		AC97_CodecCmd(WRITE,0x26, 0x4700);		// Enable PR3(VREF, I/P PGA's, DAC's, ADC's, Mixer, O/P's)

	 	//Disp("AC97 Codec 0x26 Reg.: 0x%x\n\n", AC97_CodecCmd(READ,0x26,0x0000));
		AC97_CodecCmd(WRITE,0x3c, 0xfbff);		// Enable MBIAS generator
		Delay(1000);
		
		AC97_CodecCmd(WRITE,0x26, 0x4300);		// Enable PR2(I/P PGA's and mixers)
		AC97_CodecCmd(WRITE,0x3C, 0xfbcf);		// Enable ADC L/R
		AC97_CodecCmd(WRITE,0x26, 0x4200);		// Enable Stereo ADC 
		AC97_CodecCmd(WRITE,0x26, 0x0200);		// Enable PR6 (O/P PGA's)
		AC97_CodecCmd(WRITE,0x3E, 0xff9f);		// Enable LINE L/R PGA

		AC97_CodecCmd(WRITE,0x2A,0x1);		//Variable Rate Enable	
		Disp("VRA Enable(1)/Disable(0): 0x%x\n",(0x1&AC97_CodecCmd(READ,0x2A,0x0001)));

		if(uAc97Fs==8000){
		//ADC Sampling frequency 8kHz
		AC97_CodecCmd(WRITE,0x32,0x1f40);	
		}
		else if(uAc97Fs==48000){
		//ADC Sampling frequency 48kHz
		AC97_CodecCmd(WRITE,0x32,0xbb80);	
		}
		else if(uAc97Fs==44100){
		//ADC Sampling frequency 44.1kHz
		AC97_CodecCmd(WRITE,0x32,0xac44);
		}
		else if(uAc97Fs==22050){
		//ADC Sampling frequency 22.05kHz
		AC97_CodecCmd(WRITE,0x32,0x5622);	 	
		}
		
		Disp("\nAC97 Codec 0x32 Reg.: 0x%x\n\n", AC97_CodecCmd(READ,0x32,0x0000));

		AC97_CodecCmd(WRITE,0x5C, 0x2);		//ADC Slot Mapping: Left(Slot 6), Right(Slot 9)
		AC97_CodecCmd(WRITE,0x14, 0xfe12);		// Record Mux Source Selection: LINE L/R
		AC97_CodecCmd(WRITE,0x12, 0x1010);		// Unmute ADC and Set ADC Recoding Volume

	#endif

}


void AC97_PCMInDMA(u32 uRecBufferAddr, u32 uPcmSize)
{
	uAc97RecDone =0;
	
	//IRQ Setting
	INTC_SetVectAddr( NUM_DMA1, Isr_AC97_PCMIn_DMADone);
	INTC_Enable( NUM_DMA1);
	      
    //DMA Setting
    SYSC_SelectDMA(eSEL_AC_PCMIN, 1);
    DMAC_InitCh(DMA1 , DMA_A, &oAc97Dma);

    DMACH_ClearIntPending(&oAc97Dma);
	DMACH_ClearErrIntPending(&oAc97Dma);
	DMACH_Setup(DMA_A, 0x0, (u32)(AC97_BASE+rACPCMDATA), true, (u32)uRecBufferAddr, false, WORD, uPcmSize/4, HANDSHAKE, DMA1_AC_PCMin, MEM, SINGLE, &oAc97Dma);

	Disp("Supply Sound to AC97 CODEC via Line In Connector.\n");
    Disp("Press any key to record.\n");
    UART_Getc();
   	Disp("Recording...\n");

  	DMACH_Start(&oAc97Dma);

	//Transfer data enable using AC-Link
	AC97_SetTransferCh(PCM_IN, DMA);
 
    while(uAc97RecDone ==0)
    {
    	Disp(".");
        Delay(3000);
    }        
    		
    uAc97RecDone = 0;
    DMACH_Stop(&oAc97Dma);	// DMA stop
     
    INTC_Disable(NUM_DMA1);

    //AC97 PCM In Channel Finish 
    AC97_SetTransferCh(PCM_IN, OFF);
 
  	Disp("\nEnd of Record!\n");
}


void AC97_PCMOutDMA(u32 uRecBufferAddr, u32 uPcmSize)
{
	u32 uUpDownVolume;
	
	//IRQ Setting
	INTC_SetVectAddr( NUM_DMA1, Isr_AC97_PCMOut_DMADone);
	INTC_Enable( NUM_DMA1);
	      
    //DMA Setting
    SYSC_SelectDMA(eSEL_AC_PCMOUT, 1);
    DMAC_InitCh(DMA1, DMA_B, &oAc97Dma);

    DMACH_ClearIntPending(&oAc97Dma);
	DMACH_ClearErrIntPending(&oAc97Dma);
	DMACH_Setup(DMA_B, 0x0, (u32)uRecBufferAddr, false, (u32)(AC97_BASE+rACPCMDATA), true, WORD, uPcmSize/4, HANDSHAKE, MEM, DMA1_AC_PCMout, SINGLE, &oAc97Dma);
								
	Disp("\nListen to Sound via Speak Out Connector.\n");
	Disp("Press any key to play.\n");
    UART_Getc();
   	Disp("\nNow Play...\n");
	Disp("To Volume Up, Press the 'u' key.\n");
	Disp("To Volume Down, Press the 'd' key.\n");
	Disp("\nIf you want to exit, Press the 'x' key.\n");
	Disp("Headphone Volume Register = 0x%x\n", uOutputVolume);

  	DMACH_Start(&oAc97Dma);

	// Transfer data enable  using AC-Link
	AC97_SetTransferCh(PCM_OUT, DMA);
 
    while(1)
    {
    	uUpDownVolume = UART_Getc();

		if( (uUpDownVolume == 'x') | (uUpDownVolume == 'X')) 
		break;

	    AC97_SetOutputVolume(uUpDownVolume);
    }        
    		
    DMACH_Stop(&oAc97Dma);		// DMA stop
     
    INTC_Disable(NUM_DMA1);

    //AC97 PCM In Channel Finish 
    AC97_SetTransferCh(PCM_OUT, OFF);
 
  	Disp("\nEnd of Play!\n");	
}

void AC97_MICInDMA(u32 uRecBufferAddr, u32 uPcmSize)
{
	//IRQ Setting
	INTC_SetVectAddr( NUM_DMA1, Isr_AC97_MICIn_DMADone);
	INTC_Enable(NUM_DMA1);
	      
    //DMA Setting
    SYSC_SelectDMA(eSEL_AC_MICIN, 1);
    DMAC_InitCh(DMA1, DMA_A, &oAc97Dma);

    DMACH_ClearIntPending(&oAc97Dma);
	DMACH_ClearErrIntPending(&oAc97Dma);
	DMACH_Setup(DMA_A, 0x0, (u32)(AC97_BASE+rACMICDATA), true, (u32)uRecBufferAddr, false, WORD, uPcmSize/4, HANDSHAKE, DMA1_AC_MICin, MEM, SINGLE, &oAc97Dma);

	#if (AC97_CODEC_NAME== STAC9767)
		Disp("Supply Sound to AC97 CODEC via MIC In Connector.\n");
	#elif (AC97_CODEC_NAME== WM9713)	
		Disp("Supply Sound to AC97 CODEC via PCM In Connector.\n");
	#endif

    Disp("Press any key to start record.\n");
    UART_Getc();
   	Disp("Recording...\n");

  	DMACH_Start(&oAc97Dma);

	// Transfer data enable  using AC-Link
	AC97_SetTransferCh(MIC_IN, DMA);
 
    while(uAc97RecDone ==0)
    {
    	Disp(".");
        Delay(3000);
    }        
    		
    uAc97RecDone = 0;
    DMACH_Stop(&oAc97Dma);		// DMA stop
     
    INTC_Disable(NUM_DMA1);

    //AC97 PCM In Channel Finish 
    AC97_SetTransferCh(MIC_IN, OFF);

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


void AC97_PCMInINT(u32 uRecBufferAddr, u32 uPcmSize)
{
	uAc97RecDone =0;

	uRecBuffer = (u32 *) uRecBufferAddr;
	uEndRecBuffer = uRecBuffer + uPcmSize;
    
	//IRQ Initialization
	INTC_ClearVectAddr();
	INTC_SetVectAddr(NUM_AC97, Isr_AC97_PCMIn);
	INTC_Enable(NUM_AC97);

	Disp("Supply Sound to AC97 CODEC via Line In Connector.\n");
    Disp("Press any key to record.\n");
    UART_Getc();
   	Disp("Recording...\n");

	AC97_ClearInt(PCMIN_THRESHOLD_INT);
	AC97_EnableInt(PCMIN_THRESHOLD_INT);

	AC97_SetTransferCh(PCM_IN, PIO);	
	
	while(1)
	{
	       if(uAc97RecDone == 1)
		break;	
	}

	AC97_SetTransferCh(PCM_IN, OFF);	
	
	INTC_Disable(NUM_AC97);
	AC97_DisableInt(PCMIN_THRESHOLD_INT);

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


void AC97_PCMOutINT(u32 uRecBufferAddr, u32 uPcmSize)
{
	uAc97PlayDone =0;

	uRecBuffer = (u32 *) uRecBufferAddr;
	uEndRecBuffer = uRecBuffer + uPcmSize;
    
	//IRQ Initialization
	INTC_ClearVectAddr();
	INTC_SetVectAddr(NUM_AC97, Isr_AC97_PCMOut);
	INTC_Enable(NUM_AC97);

	Disp("\nListen to Sound via Speak Out Connector.\n");
	Disp("Press any key to play.\n");
    UART_Getc();
   	Disp("\nNow Play...\n");
	Disp("Headphone Volume Register = 0x%x\n", uOutputVolume);

	AC97_ClearInt(PCMIN_THRESHOLD_INT);
	AC97_EnableInt(PCMOUT_THRESHOLD_INT);

	AC97_SetTransferCh(PCM_OUT, PIO);	
	
	while(1)
	{
	       if(uAc97PlayDone == 1)
		break;	
	}

	AC97_SetTransferCh(PCM_OUT, OFF);	
	
	INTC_Disable(NUM_AC97);
	AC97_DisableInt(PCMOUT_THRESHOLD_INT);

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


void AC97_MICInINT(u32 uRecBufferAddr, u32 uPcmSize)
{
	uAc97RecDone =0;

	uRecBuffer = (u32 *) uRecBufferAddr;
	uEndRecBuffer = uRecBuffer + uPcmSize;
    
	//IRQ Initialization
	INTC_ClearVectAddr();
	INTC_SetVectAddr(NUM_AC97, Isr_AC97_MICIn);
	INTC_Enable(NUM_AC97);

	#if (AC97_CODEC_NAME== STAC9767)
		Disp("Supply Sound to AC97 CODEC via MIC In Connector.\n");
	#elif (AC97_CODEC_NAME== WM9713)	
		Disp("Supply Sound to AC97 CODEC via PCM In Connector.\n");
	#endif
	
    Disp("Press any key to record.\n");
    UART_Getc();
   	Disp("Recording...\n");

	AC97_ClearInt(MICIN_THRESHOLD_INT);
	AC97_EnableInt(MICIN_THRESHOLD_INT);

	AC97_SetTransferCh(MIC_IN, PIO);	
	
	while(1)
	{
	    if(uAc97RecDone == 1)
		break;	
	}

	AC97_SetTransferCh(MIC_IN, OFF);	
	
	INTC_Disable(NUM_AC97);
	AC97_DisableInt(MICIN_THRESHOLD_INT);

	Disp("\nEnd of Record!\n");	

}


void AC97_SetOutputVolume(u8 uUpDownVolume)
{
	if( ( uUpDownVolume == 'u') | (uUpDownVolume == 'U') )
	{	
		if (uOutputVolume == 0x0000) 
		{
			Disp("\nLimit Volume Range!");
		} 
		else 
		{
			uOutputVolume -= 0x0101;
			AC97_CodecCmd(WRITE,0x04, uOutputVolume);		// PCM out Volume Up
			Disp("\nHeadphone Volume Level (In AC97 Codec 04h Reg.): 0x%x", uOutputVolume);
		}
	}
				
	if ( ( uUpDownVolume == 'd') | (uUpDownVolume == 'D') ) 
	{	
		#if (AC97_CODEC_NAME== STAC9767)
		if (uOutputVolume == 0x1F1F) 
		#elif (AC97_CODEC_NAME== WM9713)	
		if (uOutputVolume == 0x3F3F) 
		#endif
		{
			Disp("\nLimit Volume Range!");
		} 
		else 
		{
			uOutputVolume += 0x0101;
			AC97_CodecCmd(WRITE,0x04, uOutputVolume);		// PCM out Volume Down
			Disp("\nHeadphone Volume Level (In AC97 Codec 04h Reg.): 0x%x", uOutputVolume);
		}
	}
}

void AC97_ExitCodecPCMOut(void)
{
	//DACs off
	Disp("\n\n=>DACs off PR1\n");
	AC97_CodecCmd((AC97_CMD)0,0x26,(1<<8)|(1<<9));
	AC97_ControllerState();
	Disp("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_CodecCmd(READ,0x26,0x0000));	

	//Analog off
	Disp("\n=>Analog off PR2\n");
	AC97_CodecCmd((AC97_CMD)0,0x26,(1<<8)|(1<<9)|(1<<10));
	AC97_ControllerState();
	Disp("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_CodecCmd(READ,0x26,0x0000));	

	//Digital I/F off
	Disp("\n=>Digital I/F off PR4\n");
	AC97_CodecCmd((AC97_CMD)0,0x26,(1<<8)|(1<<9)|(1<<10)|(1<<12));
	AC97_ControllerState();
	Disp("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_CodecCmd(READ,0x26,0x0000));	
}

void AC97_ExitCodecPCMIn(u16 uDACsOff)
{
	//ADCs off
	Disp("\n\n=>ADCs off PR0\n");
	AC97_CodecCmd(WRITE,0x26,(1<<8));
	AC97_ControllerState();
	Disp("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_CodecCmd(READ,0x26,0x0000));

	if(uDACsOff == 1)
	{
		//DACs off
		Disp("\n\n=>DACs off PR1\n");
		AC97_CodecCmd(WRITE,0x26,(1<<8)|(1<<9));
		AC97_ControllerState();
		Disp("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_CodecCmd(READ,0x26,0x0000));
	}
	//Analog off
	Disp("\n=>Analog off PR2\n");
	AC97_CodecCmd(WRITE,0x26,(1<<8)|(1<<9)|(1<<10));
	AC97_ControllerState();
	Disp("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_CodecCmd(READ,0x26,0x0000));	

	//Digital I/F off
	Disp("\n=>Digital I/F off PR4\n");
	AC97_CodecCmd(WRITE,0x26,(1<<8)|(1<<9)|(1<<10)|(1<<12));
	AC97_ControllerState();
	Disp("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_CodecCmd(READ,0x26,0x0000));
}


void AC97_ExitCodecMICIn(u16 uDACsOff)
{
	//ADCs off
	Disp("\n\n=>ADCs off PR0\n");
	AC97_CodecCmd((AC97_CMD)0,0x26,(1<<8));
	AC97_ControllerState();
	Disp("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_CodecCmd(READ,0x26,0x0000));

	if(uDACsOff == 1)
	{
		//DACs off
		Disp("\n\n=>DACs off PR1\n");
		AC97_CodecCmd((AC97_CMD)0,0x26,(1<<8)|(1<<9));
		AC97_ControllerState();
		Disp("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_CodecCmd(READ,0x26,0x0000));
	}
	
	//Analog off
	Disp("\n=>Analog off PR2\n");
	AC97_CodecCmd((AC97_CMD)0,0x26,(1<<8)|(1<<9)|(1<<10));
	AC97_ControllerState();
	Disp("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_CodecCmd(READ,0x26,0x0000));	

	//Digital I/F off
	Disp("\n=>Digital I/F off PR4\n");
	AC97_CodecCmd((AC97_CMD)0,0x26,(1<<8)|(1<<9)|(1<<10)|(1<<12));
	AC97_ControllerState();
	Disp("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_CodecCmd(READ,0x26,0x0000));	
}


//ISR
void __irq Isr_AC97_CodecReady(void)
{ 
	u32 uState;

	uState= Inp32(AC97_BASE+rACGLBSTAT); 
	
	if ( (uState & 0x400000))
	{
		uCodecReadyIrq = 1;
		Disp("Codec Ready!\n");	
	}
	
	INTC_Disable(NUM_AC97);
	AC97_DisableInt(CODEC_READY_INT);	//Sholud be located after uState= Inp32(AC97_BASE+rACGLBSTAT); 
	
	AC97_ClearInt(CODEC_READY_INT);
	INTC_ClearVectAddr();
}

void __irq Isr_AC97_PCMIn_DMADone(void)
{
	INTC_Disable(NUM_DMA1);

	Disp("\nPCM In DMA Done.\n");
	uAc97RecDone = 1;

	DMACH_ClearIntPending(&oAc97Dma);
	DMACH_ClearErrIntPending(&oAc97Dma);
	INTC_ClearVectAddr();	
}

void __irq Isr_AC97_PCMOut_DMADone(void)
{
	INTC_Disable(NUM_DMA1);

	Disp("\n~~~");
	DMAC_InitCh(DMA1 , DMA_B, &oAc97Dma);
	
	DMACH_ClearIntPending(&oAc97Dma);
	DMACH_ClearErrIntPending(&oAc97Dma);
	INTC_ClearVectAddr();	

	INTC_Enable(NUM_DMA1);

	DMACH_Setup(DMA_B, 0x0, (u32)REC_BUF, false, (u32)(AC97_BASE+rACPCMDATA), true, WORD, AC97_REC_LEN/4, HANDSHAKE, MEM, DMA1_AC_PCMout, SINGLE, &oAc97Dma);
	DMACH_Start(&oAc97Dma);
}

void __irq Isr_AC97_MICIn_DMADone(void)
{
	INTC_Disable(NUM_DMA1);

	Disp("\nMIC In DMA Done.\n");
	uAc97RecDone = 1;

	DMACH_ClearIntPending(&oAc97Dma);
	DMACH_ClearErrIntPending(&oAc97Dma);
	INTC_ClearVectAddr();	
}

void __irq Isr_AC97_PCMIn(void)
{
	u32 uGlbStatus, i; 

	INTC_Disable(NUM_AC97);
	
	uGlbStatus= Inp32(AC97_BASE+rACGLBSTAT);
	
	if (uGlbStatus & AC97_PCM_IN_THRESHOLD)
	{
		for(i=0; i<PCM_IN_TRIGGER; i++)
		{
			*(uRecBuffer++) = Inp32(AC97_BASE+rACPCMDATA);			

			if(uRecBuffer == uEndRecBuffer)  
			break;	
		}			
	}
	
	AC97_DisableInt(PCMIN_THRESHOLD_INT);

	if(uRecBuffer == uEndRecBuffer) 
		uAc97RecDone =1;	

	AC97_ClearInt(PCMIN_THRESHOLD_INT);
	INTC_ClearVectAddr();

	AC97_EnableInt(PCMIN_THRESHOLD_INT);
	INTC_Enable(NUM_AC97);
}

void __irq Isr_AC97_PCMOut(void)
{
	u32 uGlbStatus, i; 

	INTC_Disable(NUM_AC97);
	
	uGlbStatus= Inp32(AC97_BASE+rACGLBSTAT);
	
	if (uGlbStatus & AC97_PCM_OUT_THRESHOLD)
	{
		for(i=0; i<PCM_OUT_TRIGGER; i++)
		{	
			AC97Outp32(rACPCMDATA, *(uRecBuffer++));	

			if(uRecBuffer == uEndRecBuffer)  
			break;	
		}			
	}
	AC97_DisableInt(PCMOUT_THRESHOLD_INT);
	
	if(uRecBuffer == uEndRecBuffer) 
		uAc97PlayDone =1;	

	AC97_ClearInt(PCMOUT_THRESHOLD_INT);
	INTC_ClearVectAddr();
	
	AC97_EnableInt(PCMOUT_THRESHOLD_INT);
	INTC_Enable(NUM_AC97);
}

void __irq Isr_AC97_MICIn(void)
{
	u32 uGlbStatus, i; 

	INTC_Disable(NUM_AC97);
	
	uGlbStatus= Inp32(AC97_BASE+rACGLBSTAT);
	
	if (uGlbStatus & AC97_MIC_IN_THRESHOLD)
	{
		for(i=0; i<PCM_IN_TRIGGER; i++)
		{
			*(uRecBuffer++) = Inp32(AC97_BASE+rACMICDATA);			

			if(uRecBuffer == uEndRecBuffer)  
			break;	
		}			
	}
	AC97_DisableInt(MICIN_THRESHOLD_INT);

	if(uRecBuffer == uEndRecBuffer) 
		uAc97RecDone =1;	
	
	AC97_ClearInt(MICIN_THRESHOLD_INT);
	INTC_ClearVectAddr();

	AC97_EnableInt(MICIN_THRESHOLD_INT);
	INTC_Enable(NUM_AC97);
}

⌨️ 快捷键说明

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