📄 ac97.c
字号:
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);
}
}
}
void Download_PCM_File(void)
{
pISR_UART1 = (unsigned)RxInt;
rINTMSK = ~( BIT_UART1);
rINTSUBMSK = ~(BIT_SUB_RXD1);
AC97_BUF = (U8 *)DOWN_BUF;
AC97_temp = AC97_BUF;
printf("\nDownload the PCM(no ADPCM) file via Serial Port Transmit in DNW (With header & CS)!\n");
printf("Max of PCM Size: 4M bytes\n");
while(((unsigned int)AC97_temp - (unsigned int)AC97_BUF) < 4)
{
Led_Display(0);
Delay(1500);
Led_Display(15);
Delay(1500);
}
AC97_size = *(AC97_BUF) | *(AC97_BUF + 1)<<8 | *(AC97_BUF + 2)<<16 | *(AC97_BUF + 3)<<24;
printf("\nNow, Downloading... [ File Size : %7d( 0)]",AC97_size);
while(((unsigned int)AC97_temp - (unsigned int)AC97_BUF) < AC97_size)
printf("\b\b\b\b\b\b\b\b%7d)",(unsigned int)AC97_temp - (unsigned int)AC97_BUF);
printf("\b\b\b\b\b\b\b\b%7d)]\n",(unsigned int)AC97_temp - (unsigned int)AC97_BUF);
rINTSUBMSK |= BIT_SUB_RXD1;
AC97_size = *(AC97_BUF + 0x2c) | *(AC97_BUF + 0x2d)<<8 | *(AC97_BUF + 0x2e)<<16 | *(AC97_BUF + 0x2f)<<24;
AC97_size = (AC97_size>>1)<<1;
AC97_fs = *(AC97_BUF + 0x1c) | *(AC97_BUF + 0x1d)<<8 | *(AC97_BUF + 0x1e)<<16 | *(AC97_BUF + 0x1f)<<24;
Play_AC97_BUF = (U32 *)(AC97_BUF + 0x30); //DNW Header + PCM File Header => OffSet: 0x30
printf("Sample PCM Data Size = %d\n", AC97_size);
printf("Sampling Frequency = %d Hz\n", AC97_fs);
}
void AC97_PCMout_DMA1(unsigned int PCM_Size)
{
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);
//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)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);
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("\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);
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");
}
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_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
while(1)
{
if(AC97_Out_INT_Exit == 1)
break;
}
rAC_GLBCTRL &= ~(1<<12); //PCM Out Transfer PIO Mode Off
rINTSUBMSK|=(BIT_SUB_WDT|BIT_SUB_AC97);
rINTMSK|=(BIT_WDT_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 = (unsigned)DMA2_Rec_Done;
ClearPending(BIT_DMA);
rSUBSRCPND=(BIT_SUB_DMA2);
rINTMSK = ~(BIT_DMA);
rINTSUBMSK=~(BIT_SUB_DMA2);
//DMA2 Initialize
rDISRC2 = ((unsigned int)0x5B000018); //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 = (U32)(1<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(1<<22)+(2<<20)+(PCM_Size/4);
rDMAREQSEL2 = (28<<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);
rSUBSRCPND=(BIT_SUB_DMA2);
rDMASKTRIG2 = (1<<2); //DMA2 stop
rINTMSK |= (BIT_DMA);
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_WDT_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");
getchar();
printf("Recording...\n");
ClearPending(BIT_WDT_AC97);
rSUBSRCPND=(BIT_SUB_AC97);
rINTMSK=~(BIT_WDT_AC97);
rINTSUBMSK=~(BIT_SUB_AC97);
rAC_GLBCTRL = 0x2040C; //PCM In channel threshold INT enable, PIO Mode On
while(1)
{
if(AC97_In_INT_Exit == 1)
break;
}
rAC_GLBCTRL &= ~(1<<10); //PCM In Transfer PIO Mode Off
rINTSUBMSK|=(BIT_SUB_AC97);
rINTMSK|=(BIT_WDT_AC97);
printf("\nEnd of Record!\n");
}
void AC97_MICin_DMA3(unsigned int MIC_Size)
{
Rec_AC97_BUF = (unsigned int *)(DOWN_BUF);
ClearPending(BIT_DMA);
rSUBSRCPND=(BIT_SUB_DMA3);
//IRQ Initialize
pISR_DMA = (unsigned)DMA3_Rec_Done;
rINTMSK=~(BIT_DMA);
rINTSUBMSK=~(BIT_SUB_DMA3);
//DMA3 Initialize
rDISRC3 = ((unsigned int)0x5B00001C); //MIC Input Data FIFO
rDISRCC3 = (1<<1) + (1<<0); //APB, Fix
rDIDST3 = (int)Rec_AC97_BUF; //Record AC97_BUF initializ
rDIDSTC3 = (0<<1) + (0<<0); //AHB, Increment
rDCON3 = (U32)(1<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(1<<22)+(2<<20)+(MIC_Size/4);
rDMAREQSEL3 = (29<<1) + (1<<0);
printf("Are you ready to record voice via MIC on SMDK2460?\n");
printf("Press any key to start record.\n");
getchar();
printf("Recording...\n");
rDMASKTRIG3 = (0<<2) + (1<<1) + 0; //No-stop, DMA3 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)
{
printf(".");
Delay(3000);
//printf("STAT3: 0x%x CURR_TC: 0x%x, DCDST3: 0x%x\n", rDSTAT3&0x300000, rDSTAT3&0xfffff, rDCDST3);
}
AC97_Rec_Done = 0;
ClearPending(BIT_DMA);
rSUBSRCPND=(BIT_SUB_DMA3);
rDMASKTRIG3 = (1<<2); //DMA3 stop
rINTMSK |= (BIT_DMA);
rINTSUBMSK |=(BIT_SUB_DMA3);
//AC97 MIC In Channel Finish
rAC_GLBCTRL &= ~(1<<9); //MIC In Transfer Mode Off
printf("\nEnd of Record!\n");
}
void AC97_MICin_INT(unsigned int PCM_Size)
{
//Record AC97_BUF initialize
Rec_AC97_BUF = (unsigned int *)(DOWN_BUF);
Play_AC97_BUF = Rec_AC97_BUF;
End_AC97_BUF = (Rec_AC97_BUF + PCM_Size/4);
//IRQ Initialization
pISR_WDT_AC97= (unsigned)Irq_AC97_MICin;
printf("Are you ready to record voice via MIC on SMDK2460?\n");
printf("Press any key to start record.\n");
getchar();
printf("Recording...\n");
ClearPending(BIT_WDT_AC97);
rSUBSRCPND=(BIT_SUB_AC97);
rINTMSK=~(BIT_WDT_AC97);
rINTSUBMSK=~(BIT_SUB_AC97);
rAC_GLBCTRL = 0x1010C; //MIC In channel threshold INT enable, PIO Mode On
while(1)
{
if(AC97_In_INT_Exit == 1)
break;
}
rAC_GLBCTRL &= ~(1<<8); //MIC In Transfer PIO Mode Off
rINTSUBMSK|=(BIT_SUB_AC97);
rINTMSK|=(BIT_WDT_AC97);
printf("\nEnd of Record!\n");
}
/* ISRs */
void __irq AC97_Codec_Ready(void)
{
if ( (rAC_GLBSTAT& 0x400000))
{
Codec_Ready_Irq=1;
printf("Codec Ready!\n");
rAC_GLBCTRL &= ~(0x400000); // codec ready interrupt disable
}
rSUBSRCPND=(BIT_SUB_AC97);
ClearPending(BIT_WDT_AC97);
rINTSUBMSK &= ~(BIT_SUB_AC97);
rINTMSK &=~(BIT_WDT_AC97);
}
void __irq DMA1_Play_Done(void)
{
rINTMSK = ~(BIT_DMA);
rINTSUBMSK=~(BIT_SUB_DMA2);
ClearPending(BIT_DMA);
rSUBSRCPND=(BIT_SUB_DMA1);
printf("\n~~~");
rINTMSK |= (BIT_DMA);
rINTSUBMSK |=(BIT_SUB_DMA2);
}
void __irq DMA2_Rec_Done(void)
{
ClearPending(BIT_DMA);
rSUBSRCPND=(BIT_SUB_DMA2);
AC97_Rec_Done = 1;
}
void __irq DMA3_Rec_Done(void)
{
ClearPending(BIT_DMA);
rSUBSRCPND=(BIT_SUB_DMA3);
AC97_Rec_Done = 1;
}
void __irq Irq_AC97_PCMout(void)
{
unsigned int i, AC97_Stat;
rINTMSK |=(BIT_WDT_AC97);
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
AC97_Out_INT_Exit =1;
}
rSUBSRCPND=(BIT_SUB_AC97);
ClearPending(BIT_WDT_AC97);
rINTSUBMSK &= ~(BIT_SUB_AC97);
rINTMSK &= ~(BIT_WDT_AC97);
}
void __irq Irq_AC97_PCMin(void)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -