📄 ac97.c
字号:
//Disp("AC97 Codec 0x26 Reg.: 0x%x\n\n", AC97_Codec_Cmd(1,0x26,0x0000));
AC97_Codec_Cmd(0,0x3c, 0xfbff); // Enable MBIAS generator
Delay(1000);
AC97_Codec_Cmd(0,0x26, 0x4300); // Enable PR2(I/P PGA's and mixers)
AC97_Codec_Cmd(0,0x3C, 0xfbcf); // Enable ADC L/R //fbf3
AC97_Codec_Cmd(0,0x26, 0x4200); // Enable Stereo ADC //4100
AC97_Codec_Cmd(0,0x26, 0x0200); // Enable PR6 (O/P PGA's) 3c fb33
AC97_Codec_Cmd(0,0x3E, 0xff9f); // Enable LINE L/R PGA 26 0100
printf("VRA(Variable Rate) Enable(1)/Disable(0): \n");
//i = GetIntNum();
if(AC97_fs != 48000) i = 1;
if(i==1) AC97_Codec_Cmd(0,0x2A,0x1); //Variable Rate Enable
else AC97_Codec_Cmd(0,0x2A,0x0); //Variable Rate Disable
printf("VRA : 0x%x\n",(0x1&AC97_Codec_Cmd(1,0x2A,0x0001)));
//ADC sampling freq.
AC97_CodecSampleFreq(0x32, AC97_fs);
printf("\nAC97 Codec 0x32 Reg.: 0x%x\n\n", AC97_Codec_Cmd(1,0x32,0x0000));
AC97_Codec_Cmd(0,0x14, 0xfe12); // Record Mux Source Selection: LINE L/R
AC97_Codec_Cmd(0,0x12, 0x1010); // Unmute ADC and Set ADC Recoding Volume
#endif
}
void AC97_CodecInit_PCMOut( unsigned short AC97_fs)
{
int i;
#if (AC97_CODEC_NAME== STAC9767)
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
printf("Current Headphone Volume level : 0x%04x\n",Input_Volume);
#elif (AC97_CODEC_NAME== AC97WM9713)
AC97_Codec_Cmd(0,0x26, 0x4f00); // Enable PR5(Internal Clock, AC-link I/F)
AC97_Codec_Cmd(0,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_Codec_Cmd(1,0x26,0x0000));
AC97_Codec_Cmd(0,0x3c, 0xfbff); // Enable MBIAS generator
Delay(1000);
AC97_Codec_Cmd(0,0x26, 0x4300); // Enable PR2(I/P PGA's and mixers)
AC97_Codec_Cmd(0,0x3C, 0xfbf3); // Enable HPL/R Mixer
AC97_Codec_Cmd(0,0x26, 0x4100); // Enable PR1(Stereo DAC)
AC97_Codec_Cmd(0,0x3C, 0xfb33); // Enable DAC L/R
AC97_Codec_Cmd(0,0x26, 0x0100); // Enable PR6 (O/P PGA's)
AC97_Codec_Cmd(0,0x3E, 0xf9ff); // Enable PR6 (O/P PGA's)
printf("VRA(Variable Rate) Enable(1)/Disable(0): \n");
//i = GetIntNum();
if(AC97_fs != 48000) i = 1;
if(i==1) AC97_Codec_Cmd(0,0x2A,0x1); //Variable Rate Enable
else AC97_Codec_Cmd(0,0x2A,0x0); //Variable Rate Disable
printf("VRA : 0x%x\n",(0x1&AC97_Codec_Cmd(1,0x2A,0x0001)));
//DAC Sampling frequency
AC97_CodecSampleFreq(0x2c, AC97_fs);
printf("\nAC97 Codec 0x2C Reg.: 0x%x\n\n", AC97_Codec_Cmd(1,0x2C,0x0000));
AC97_Codec_Cmd(0,0x1c, 0x00a0); // HPL/R PGA input select HPMIXL/R
AC97_Codec_Cmd(0,0x04,0x0707); // Set HPL/R Volume
Output_Volume = AC97_Codec_Cmd(1,0x04,0x00000); //HP out volume
AC97_Codec_Cmd(0,0x0c,0x6808); // Unmute DAC to HP mixer path
AC97_Codec_Cmd(0,0x04,0x0A0A); // Unmute HPL/R
#endif
}
//return
void AC97_CodecInit_MICIn(unsigned short AC97_fs)
{
#if (AC97_CODEC_NAME== STAC9767)
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
#elif (AC97_CODEC_NAME== AC97WM9713)
int i;
AC97_Codec_Cmd(0,0x26, 0x4f00); // Enable PR5(Internal Clock, AC-link I/F)
AC97_Codec_Cmd(0,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_Codec_Cmd(1,0x26,0x0000));
AC97_Codec_Cmd(0,0x3c, 0xfbff); // Enable MBIAS generator
Delay(1000);
AC97_Codec_Cmd(0,0x26, 0x4300); // Enable PR2(I/P PGA's and mixers)
AC97_Codec_Cmd(0,0x3C, 0xfbcf); // Enable ADC L/R
AC97_Codec_Cmd(0,0x26, 0x4200); // Enable Stereo ADC
AC97_Codec_Cmd(0,0x26, 0x0200); // Enable PR6 (O/P PGA's)
//AC97_Codec_Cmd(0,0x3E, 0xff9f); // Enable LINE L/R PGA for line in
printf("0. disable mic bias 1. enable mic bias [1]\n");
//i = GetIntNum();
//if(i==0) AC97_Codec_Cmd(0,0x3E, 0xfff0); // diable mic bias, Enable MIC L/R PGA
//else
AC97_Codec_Cmd(0,0x3E, 0xbff0); // Enable mic bias, MIC L/R PGA
printf("VRA(Variable Rate) Enable(1)/Disable(0): \n");
//i = GetIntNum();
if(AC97_fs != 48000) i = 1;
if(i==1) AC97_Codec_Cmd(0,0x2A,0x1); //Variable Rate Enable
else AC97_Codec_Cmd(0,0x2A,0x0); //Variable Rate Disable
printf("VRA : 0x%x\n",(0x1&AC97_Codec_Cmd(1,0x2A,0x0001)));
//ADC Sampling frequency
AC97_CodecSampleFreq(0x32, AC97_fs);
printf("\nAC97 Codec 0x32 Reg.: 0x%x\n\n", AC97_Codec_Cmd(1,0x32,0x0000));
AC97_Codec_Cmd(0,0x5C, 0x2); //ADC Slot Mapping: Left(Slot 6), Right(Slot 9)
/*
AC97_Codec_Cmd(0,0x14, 0xfe12); // Record Mux Source Selection: LINE L/R
AC97_Codec_Cmd(0,0x12, 0x1010); // Unmute ADC and Set ADC Recoding Volume
*/
printf("0. mic bias = 0.9 AVDD = 2.97V 1. mic bias = 0.75 VDD = 2.475V [1]\n");
//i = GetIntNum();
//if(i==0) AC97_Codec_Cmd(0,0x22, 0x4040); //MIC Preamp Contorl : MIC2A only, 12dB, MICBias
//else
AC97_Codec_Cmd(0,0x22, 0x4060); //MIC Preamp Contorl : MIC2A only, 12dB, MICBias
AC97_Codec_Cmd(0,0x10, 0x68); //Unmute MIC routing : unmute MICA, MICA only
AC97_Codec_Cmd(0,0x14, 0xfe00); //Record Mux Source Selection: MICA
AC97_Codec_Cmd(0,0x12, 0x1010); // Unmute ADC and Set ADC Recoding Volume
#endif
}
void AC97_CodecExit_PCMOut(void)
{
//DACs off
printf("\n\n=>DACs off PR1\n");
AC97_Codec_Cmd(0,0x26,(1<<8)|(1<<9));
AC97_Controller_State();
printf("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 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 0x26 Reg.: 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));
}
void AC97_CodecExit_PCMIn(unsigned short DACs_off)
{
//ADCs off
printf("\n\n=>ADCs off PR0\n");
AC97_Codec_Cmd(0,0x26,(1<<8));
AC97_Controller_State();
printf("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));
if(DACs_off == 1)
{
//DACs off
printf("\n\n=>DACs off PR1\n");
AC97_Codec_Cmd(0,0x26,(1<<8)|(1<<9));
AC97_Controller_State();
printf("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 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 0x26 Reg.: 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));
}
void AC97_CodecExit_MICIn(unsigned short DACs_off)
{
//ADCs off
printf("\n\n=>ADCs off PR0\n");
AC97_Codec_Cmd(0,0x26,(1<<8));
AC97_Controller_State();
printf("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));
if(DACs_off == 1)
{
//DACs off
printf("\n\n=>DACs off PR1\n");
AC97_Codec_Cmd(0,0x26,(1<<8)|(1<<9));
AC97_Controller_State();
printf("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 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 0x26 Reg.: 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));
}
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%04x\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%04x\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%04x", 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%04x", Output_Volume);
}
}
}
////////////////////////////////////
//pcm out
//byte
void AC97_PCMout_DMA1(unsigned int Addr, unsigned int PCM_Size)
{
unsigned int AC_PCMADDR, AC97_Fifoaddr1, AC97_Fifoaddr2;
pISR_DMA= (unsigned)DMA1_Play_Done;
ClearPending(BIT_DMA);
rSUBSRCPND=(BIT_SUB_DMA1);
rINTMSK = ~(BIT_DMA);
rINTSUBMSK=~(BIT_SUB_DMA1);
//Play_AC97_BUF=(unsigned int *)(DOWN_BUF +0x30);
//Play_AC97_BUF=(unsigned int *)PCM_TESTPLAYINGDATA_BASE;
//DMA Ch1 for PCMInitialize
rDISRC1 = (int)Addr;
rDISRCC1 = (0<<1) + (0<<0); //The source is in the system bus(AHB), Increment
rDIDST1 = ((unsigned int)0x5B000018); //PCM Out Data Fifo
rDIDSTC1 = (1<<1) + (1<<0); //The destination is in the peripheral bus(APB), Fixed
rDCON1 = (U32)(1<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(0<<22)+(2<<20)+(PCM_Size/4);//[28] 0 unit, [20] 2'b10 word. [19:0]count
rDMASKTRIG1 = (0<<2) + (1<<1) + (1<<0); //No-stop[2], DMA1 channel On[1], No-sw trigger[0]
rDMAREQSEL1 = (27<<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("To pause, Press the '0' key.\n");
printf("To continue, Press the '1' 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 = AC97_PCM_OUT_UNDERRUN| AC97_PCM_OUT_MODE_DMA |AC97_TRANSFERDATA_EN| AC97_ACLINK_ON;
// 21 13 3 2
//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;
else if(Volume_Control == '0')
rAC_GLBCTRL = rAC_GLBCTRL & ~(AC97_PCM_OUT_MODE_DMA);
else if(Volume_Control == '1')
rAC_GLBCTRL = rAC_GLBCTRL | AC97_PCM_OUT_MODE_DMA;
PCM_Out_Volume(Volume_Control);
/*
AC_PCMADDR = rAC_PCMADDR ;
AC97_Fifoaddr1 = (AC_PCMADDR &0x1f000000) >>24 ;//fifo index read
AC97_Fifoaddr2 = (AC_PCMADDR &0x1f00) >>8 ;//fifo index write
printf("fifo read%d, write%d\n", AC97_Fifoaddr1, AC97_Fifoaddr2);*/
}
ClearPending(BIT_DMA);
rSUBSRCPND=(BIT_SUB_DMA1);
rDMASKTRIG1 = (1<<2); //DMA1 stop
rINTMSK |= (BIT_DMA);
rINTSUBMSK |=(BIT_SUB_DMA1);
//AC97 PCM In Channel Finish
rAC_GLBCTRL &= ~(1<<13); //PCM Out Transfer Mode Off
printf("\nEnd of Play!\n");
}
//pcmsize : byte
void AC97_PCMout_INT(unsigned int PCM_Size)
{
unsigned int AC_PCMADDR, AC97_Fifoaddr1, AC97_Fifoaddr2;
//Record AC97_BUF initialize
//Rec_AC97_BUF = (unsigned int *)(DOWN_BUF);
//End_AC97_BUF = (Play_AC97_BUF + PCM_Size/4);
//Play_AC97_BUF = (Rec_AC97_BUF + 0x30);
//End_AC97_BUF = (Rec_AC97_BUF + 0x30 + PCM_Size/4);
Play_AC97_BUF=(unsigned int *)PCM_TESTPLAYINGDATA_BASE;
End_AC97_BUF = (unsigned int *)(PCM_TESTPLAYINGDATA_BASE + PCM_Size/4);
//IRQ Initialization
pISR_WDT_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_WDT_AC97);
rSUBSRCPND=(BIT_SUB_AC97);
rINTMSK=~(BIT_WDT_AC97);
rINTSUBMSK=~(BIT_SUB_AC97);
//rAC_GLBCTRL = 0x4100C; //PCM Out channel threshold INT enable, PIO Mode On
rAC_GLBCTRL = AC97_PCM_OUT_UNDERRUN|AC97_PCM_OUT_THRESHOLD | AC97_PCM_OUT_MODE_PIO |AC97_TRANSFERDATA_EN| AC97_ACLINK_ON;
// 21 18 13 3 2
while(1)
{
if(AC97_Out_INT_Exit == 1) break;
Volume_Control=Uart_GetKey();
//Volume_Control=getchar();
if( (Volume_Control == 'x') | (Volume_Control == 'X'))
{
printf("quit");
//g_test = 1;
//rAC_GLBCTRL = rAC_GLBCTRL & ~(AC97_PCM_OUT_MODE_PIO);
rAC_GLBCTRL = rAC_GLBCTRL & ~(AC97_PCM_OUT_MODE_PIO|AC97_PCM_OUT_THRESHOLD);
rINTSUBMSK|=(BIT_SUB_AC97);
break;
}
else if(Volume_Control == '0')
{
//rAC_GLBCTRL = rAC_GLBCTRL & ~(AC97_PCM_OUT_MODE_PIO);
//g_test = 1;
rAC_GLBCTRL = rAC_GLBCTRL & ~(AC97_PCM_OUT_MODE_PIO|AC97_PCM_OUT_THRESHOLD);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -