📄 ac97.c
字号:
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 + -