📄 ac97.c
字号:
rINTMSK=~(BIT_AC97_NFLASH);
rINTSUBMSK=~(BIT_SUB_AC97);
rAC_GLBCTRL = 0x2040C; //PCM In channel threshold INT enable, PIO Mode On
while(1)
{
if(PCM_In_INT_Exit == 1)
break;
}
rAC_GLBCTRL &= ~(1<<10); //PCM In Transfer PIO Mode Off
rINTSUBMSK|=(BIT_SUB_AC97);
rINTMSK|=(BIT_AC97_NFLASH);
Uart_Printf("\nEnd of Record!\n");
}
void AC97_MICin_DMA2(U32 MIC_Size)
{
Rec_AC97_BUF = (U32 *)(DOWN_BUF);
//IRQ Initialize
pISR_DMA = (unsigned)DMA2_Rec_Done;
rINTMSK=~(BIT_DMA);
rINTSUBMSK = ~(BIT_SUB_DMA2);
//DMA2 Initialize
rDISRC2 = ((U32)0x4500001c); //MIC 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)+(5<<24)+(1<<23)+(1<<22)+(2<<20)+(MIC_Size/4);
Uart_Printf("Are you ready to record voice via CON28 on SMDK24A0?\n");
Uart_Printf("Press any key to start record.\n");
Uart_Getch();
Uart_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 = 0x20C; // Transfer data enable using AC-Link
while(AC97_Rec_Done ==0)
{
Uart_Printf(".");
Delay(3000);
//Uart_Printf("STAT3: 0x%x CURR_TC: 0x%x DCDST3: 0x%x\n", rDSTAT3&0x300000, rDSTAT3&0xfffff, rDCDST3);
}
AC97_Rec_Done = 0;
rDMASKTRIG2 = (1<<2); //DMA2 stop
rINTSUBMSK|=(BIT_SUB_DMA2);
rINTMSK|= (BIT_DMA);
//AC97 MIC In Channel Finish
rAC_GLBCTRL &= ~(1<<9); //MIC In Transfer Mode Off
Uart_Printf("\nEnd of Record!\n");
}
void AC97_MICin_INT(U32 PCM_Size)
{
//Record AC97_BUF initialize
Rec_AC97_BUF = (U32 *)(DOWN_BUF);
Play_AC97_BUF = Rec_AC97_BUF + 0x30;
End_AC97_BUF = (Rec_AC97_BUF + 0x30 + PCM_Size/4);
//IRQ Initialization
pISR_AC97_NFLASH= (unsigned)Irq_AC97_MICin;
Uart_Printf("Are you ready to record voice via CON28 on SMDK24A0?\n");
Uart_Printf("Press any key to start record.\n");
Uart_Getch();
Uart_Printf("Recording...\n");
ClearPending(BIT_AC97_NFLASH);
rSUBSRCPND=(BIT_SUB_AC97);
rINTMSK=~(BIT_AC97_NFLASH);
rINTSUBMSK=~(BIT_SUB_AC97);
rAC_GLBCTRL = 0x1010C; //MIC In channel threshold INT enable, PIO Mode On
while(1)
{
if(PCM_In_INT_Exit == 1)
break;
}
rAC_GLBCTRL &= ~(1<<8); //MIC In Transfer PIO Mode Off
rINTSUBMSK|=(BIT_SUB_AC97);
rINTMSK|=(BIT_AC97_NFLASH);
Uart_Printf("\nEnd of Record!\n");
}
void AC97_CodecExit_PCMOut(void)
{
//DACs off
Uart_Printf("\n\n=>DACs off PR1\n");
AC97_Codec_Cmd(0,0x26,(1<<8)|(1<<9));
AC97_Controller_State();
Uart_Printf("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));
//Analog off
Uart_Printf("\n=>Analog off PR2\n");
AC97_Codec_Cmd(0,0x26,(1<<8)|(1<<9)|(1<<10));
AC97_Controller_State();
Uart_Printf("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));
//Digital I/F off
Uart_Printf("\n=>Digital I/F off PR4\n");
AC97_Codec_Cmd(0,0x26,(1<<8)|(1<<9)|(1<<10)|(1<<12));
AC97_Controller_State();
Uart_Printf("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));
}
void AC97_CodecExit_PCMIn(U16 DACs_off)
{
//ADCs off
Uart_Printf("\n\n=>ADCs off PR0\n");
AC97_Codec_Cmd(0,0x26,(1<<8));
AC97_Controller_State();
Uart_Printf("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));
if(DACs_off == 1)
{
//DACs off
Uart_Printf("\n\n=>DACs off PR1\n");
AC97_Codec_Cmd(0,0x26,(1<<8)|(1<<9));
AC97_Controller_State();
Uart_Printf("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));
}
//Analog off
Uart_Printf("\n=>Analog off PR2\n");
AC97_Codec_Cmd(0,0x26,(1<<8)|(1<<9)|(1<<10));
AC97_Controller_State();
Uart_Printf("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));
//Digital I/F off
Uart_Printf("\n=>Digital I/F off PR4\n");
AC97_Codec_Cmd(0,0x26,(1<<8)|(1<<9)|(1<<10)|(1<<12));
AC97_Controller_State();
Uart_Printf("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));
}
void AC97_CodecExit_MICIn(U16 DACs_off)
{
//ADCs off
Uart_Printf("\n\n=>ADCs off PR0\n");
AC97_Codec_Cmd(0,0x26,(1<<8));
AC97_Controller_State();
Uart_Printf("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));
if(DACs_off == 1)
{
//DACs off
Uart_Printf("\n\n=>DACs off PR1\n");
AC97_Codec_Cmd(0,0x26,(1<<8)|(1<<9));
AC97_Controller_State();
Uart_Printf("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));
}
//Analog off
Uart_Printf("\n=>Analog off PR2\n");
AC97_Codec_Cmd(0,0x26,(1<<8)|(1<<9)|(1<<10));
AC97_Controller_State();
Uart_Printf("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));
//Digital I/F off
Uart_Printf("\n=>Digital I/F off PR4\n");
AC97_Codec_Cmd(0,0x26,(1<<8)|(1<<9)|(1<<10)|(1<<12));
AC97_Controller_State();
Uart_Printf("AC97 Codec Powerdown Ctrl/Stat 0x26 Reg.: 0x%x\n", AC97_Codec_Cmd(1,0x26,0x0000));
}
U16 AC97_Select_SamplingRate(void)
{
int i;
Uart_Printf("\nSelect ADC/DAC Rate\n");
Uart_Printf("0:22.05kHz, 1:44.1kHz, 2:48kHz\n");
i = Uart_GetIntNum();
switch(i)
{
case 0:
return 22050;
break;
case 1:
return 44100;
break;
case 2:
return 48000;
break;
default:
return 48000;
break;
}
}
void AC97_Controller_State(void)
{
U8 state;
state=(U8)(rAC_GLBSTAT);
switch(state)
{
case 0:
Uart_Printf("AC97 Controller State: Idle\n");
break;
case 1:
Uart_Printf("AC97 Controller State: Init\n");
break;
case 2:
Uart_Printf("AC97 Controller State: Ready\n");
break;
case 3:
Uart_Printf("AC97 Controller State: Active\n");
break;
case 4:
Uart_Printf("AC97 Controller State: LP\n");
break;
case 5:
Uart_Printf("AC97 Controller State: Warm\n");
break;
default:
break;
}
}
/* ISRs */
void __irq AC97_Codec_Ready(void)
{
if ( (rAC_GLBSTAT& 0x400000))
{
Codec_Ready_Irq=1;
Uart_Printf("AC97 Codec Ready!\n");
rAC_GLBCTRL &= ~(0x400000); // codec ready interrupt disable
}
rSUBSRCPND=(BIT_SUB_AC97);
rSUBSRCPND;
ClearPending(BIT_AC97_NFLASH);
rINTSUBMSK &= ~(BIT_SUB_AC97);
rINTMSK &=~(BIT_AC97_NFLASH);
}
void __irq DMA0_Play_Done(void)
{
rSUBSRCPND = BIT_SUB_DMA0;
rSUBSRCPND;
ClearPending(BIT_DMA);
Uart_Printf("@");
}
void __irq DMA1_Rec_Done(void)
{
rSUBSRCPND = BIT_SUB_DMA1;
rSUBSRCPND;
ClearPending(BIT_DMA);
AC97_Rec_Done = 1;
}
void __irq DMA2_Rec_Done(void)
{
rSUBSRCPND = BIT_SUB_DMA2;
rSUBSRCPND;
ClearPending(BIT_DMA);
AC97_Rec_Done = 1;
}
void __irq Irq_AC97_PCMout(void)
{
U32 i, AC97_Stat;
rINTMSK |=(BIT_AC97_NFLASH);
rINTSUBMSK|=(BIT_SUB_AC97);
AC97_Stat = rAC_GLBSTAT;
if (AC97_Stat & AC97_PCM_OUT_THRESHOLD)
{
for(i=0; i<PCM_OUT_TRIGGER; i++)
{
rAC_PCMDATA = *(Play_AC97_BUF++);
if(Play_AC97_BUF == End_AC97_BUF)
break;
}
}
if(Play_AC97_BUF == End_AC97_BUF)
{
rAC_GLBCTRL &= ~(0x40000); //PCM Out channel threshold INT disable
PCM_Out_INT_Exit =1;
}
rSUBSRCPND=(BIT_SUB_AC97);
rSUBSRCPND;
ClearPending(BIT_AC97_NFLASH);
rINTSUBMSK &= ~(BIT_SUB_AC97);
rINTMSK &= ~(BIT_AC97_NFLASH);
}
void __irq Irq_AC97_PCMin(void)
{
U32 AC97_Stat, i;
rINTMSK |=(BIT_AC97_NFLASH);
rINTSUBMSK|=(BIT_SUB_AC97);
AC97_Stat = rAC_GLBSTAT;
if (AC97_Stat & AC97_PCM_IN_THRESHOLD)
{
for(i=0; i<PCM_IN_TRIGGER; i++)
{
*(Play_AC97_BUF++) = rAC_PCMDATA;
if(Play_AC97_BUF == End_AC97_BUF)
break;
}
}
if(Play_AC97_BUF == End_AC97_BUF)
{
rAC_GLBCTRL &= ~(1<<17); //PCM In channel threshold INT disable
PCM_In_INT_Exit =1;
}
rSUBSRCPND=(BIT_SUB_AC97);
rSUBSRCPND;
ClearPending(BIT_AC97_NFLASH);
rINTSUBMSK &= ~(BIT_SUB_AC97);
rINTMSK &= ~(BIT_AC97_NFLASH);
}
void __irq Irq_AC97_MICin(void)
{
U32 AC97_Stat, i;
rINTMSK |=(BIT_AC97_NFLASH);
rINTSUBMSK|=(BIT_SUB_AC97);
AC97_Stat = rAC_GLBSTAT;
if (AC97_Stat & AC97_MIC_IN_THRESHOLD)
{
for(i=0; i<PCM_IN_TRIGGER; i++)
{
*(Play_AC97_BUF++) = rAC_MICDATA;
if(Play_AC97_BUF == End_AC97_BUF)
break;
}
}
if(Play_AC97_BUF == End_AC97_BUF)
{
rAC_GLBCTRL &= ~(1<<16); //PCM In channel threshold INT disable
PCM_In_INT_Exit =1;
}
rSUBSRCPND=(BIT_SUB_AC97);
rSUBSRCPND;
ClearPending(BIT_AC97_NFLASH);
rINTSUBMSK &= ~(BIT_SUB_AC97);
rINTMSK &= ~(BIT_AC97_NFLASH);
}
void __irq RxInt(void)
{
rSUBSRCPND = BIT_SUB_RXD0;
rSUBSRCPND;
ClearPending(BIT_UART0);
*AC97_temp ++= RdURXH0();
}
void __irq Muting(void)
{
if(rEINTPEND==(1<<0))
{
//Delay(1000); For Key bouncing protect!!
//Uart_Printf("EINT0 interrupt is occured\n");
rEINTPEND=(1<<0);
}
else if(rEINTPEND==(1<<1))
{
Uart_Printf("EINT1 interrupt is occured\n");
rEINTPEND=(1<<1);
}
else
{
Uart_Printf("rEINTPEND=%x\n",rEINTPEND);
rEINTPEND=((1<<0)|(1<<1));
}
ClearPending(BIT_EINT0_2);
rEINTMASK = 0x7ffff;
rINTMSK |= (BIT_EINT0_2);
if(AC97_mute) //AC97_mute
{
AC97_mute = 0;
AC97_Codec_Cmd(0,0x04, Output_Volume|0x8000);
Uart_Printf("\nAC97 Mute On...\n");
}
else //No AC97_mute
{
AC97_mute = 1;
AC97_Codec_Cmd(0,0x04, Output_Volume& ~(0x8000));
Uart_Printf("\nAC97 Mute Off...\n");
}
rEINTMASK&=~(1<<0);
rINTMSK &= ~(BIT_EINT0_2);
}
void AC97_Codec_Init( U16 AC97_fs){
AC97_Codec_Cmd(0,0x00,0x683F); //codec reset : 16bit In/Out (stac9766/67)
// AC97_Codec_Cmd(0,0x00,0xFFFF); //codec reset
// Uart_Printf("STAC9767 Codec Reset Register : 0x%x\n",AC97_Codec_Cmd(1,0x00,0x683f));
AC97_Codec_Cmd(0,0x2A,0x0001); // variable rate enable
// Uart_Printf("VRA : 0x%x\n",AC97_Codec_Cmd(1,0x2A,0x0001));
if(AC97_fs==48000){
// Sampling frequency 48kHz
AC97_Codec_Cmd(0,0x2C,0xbb80);
AC97_Codec_Cmd(0,0x32,0xbb80);
}
else if(AC97_fs==44100){
// Sampling frequency 44.1kHz
AC97_Codec_Cmd(0,0x2C,0xac44);
AC97_Codec_Cmd(0,0x32,0xac44);
}
else if(AC97_fs==22050){
// Sampling frequency 22.05kHz
AC97_Codec_Cmd(0,0x2C,0x5622); // DAC Sampling rate is 22.05kHz
AC97_Codec_Cmd(0,0x32,0x5622); // ADC Sampling rate is 22.05kHz
}
AC97_Codec_Cmd(0,0x26,0x0c00); // analog mixer section power off
AC97_Codec_Cmd(0,0x26,0x0000); // all power on
AC97_Codec_Cmd(0,0x6e,0x0000); //analog special(stac9766/67)
// AC97_Codec_Cmd(0,0x02,0x0a0a); // master volume initial
AC97_Codec_Cmd(0,0x04,0x0202); //Aux out(HP out) volume on
AC97_Codec_Cmd(0,0x78,0x0001); //ADC HPF Bypass
// AC97_Codec_Cmd(0,0x0e,0x0004); // mic in volume on
AC97_Codec_Cmd(0,0x10,0x1515); // line in volume on
AC97_Codec_Cmd(0,0x18,0x0000); // PCM out volume on
// AC97_Codec_Cmd(0,0x1a,0x0000); // record source select (Mic)
AC97_Codec_Cmd(0,0x1a,0x0505); // record source select (stereo mix)
// AC97_Codec_Cmd(0,0x6e,0x0004); // mic boost gain is 30dB
AC97_Codec_Cmd(0,0x1c,0x0909); // record gain is initial
AC97_Codec_Cmd(0,0x20,0x0000); // general purpose
// Output_Volume = AC97_Codec_Cmd(1,0x84,0x0000); //HP out volume
// Input_Volume = AC97_Codec_Cmd(1,0x90,0x0000); //Line In volume
Output_Volume = AC97_Codec_Cmd(1,0x04,0x0000); //HP out volume
Input_Volume = AC97_Codec_Cmd(1,0x10,0x0000); //Line In volume
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -