📄 ac97.c
字号:
//Record AC97_BUF initialize
Rec_AC97_BUF = (unsigned int *)(PCM_TESTPLAYINGDATA_BASE);
Play_AC97_BUF = Rec_AC97_BUF;
//IRQ Initialization
pISR_WDT_AC97= (unsigned)Irq_AC97_MICinIntTest;
printf("Are you ready to record sound via MIC-in socket on SMDK2450?\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 = 0x40C; // PIO Mode On
rAC_GLBCTRL = AC97_MIC_IN_OVERRUN | AC97_MIC_IN_THRESHOLD | AC97_MIC_IN_MODE_PIO |AC97_ACLINK_ON|AC97_TRANSFERDATA_EN;
for(i=0;i<20;i++)
{
*(Play_AC97_BUF++) = rAC_MICDATA;
AC97_FifoEmptyCntMICIN(1);
}
rAC_GLBCTRL &= ~AC97_MIC_IN_OVERRUN; //Mic in channel overrun INT disable
rAC_GLBCTRL &= ~AC97_MIC_IN_THRESHOLD; //Min in channel threshold INT disable
rAC_GLBCTRL &= ~AC97_MIC_IN_MODE_PIO; //Mic in Transfer PIO Mode Off
rINTSUBMSK|=(BIT_SUB_AC97);
rINTMSK|=(BIT_WDT_AC97);
printf("\nEnd of Record!\n");
}
void AC97_MICin_Polling(unsigned int PCM_Size)
{
// unsigned int i, fullcnt;
unsigned int i, AC97_Fifoaddr,AC97_FifoaddrR,AC97_FifoaddrW,emptycnt,fullcnt;
//Record AC97_BUF initialize
Rec_AC97_BUF=(unsigned int *)PCM_TESTPLAYINGDATA_BASE;
End_Rec_AC97_BUF = (unsigned int *)(PCM_TESTPLAYINGDATA_BASE +PCM_Size);
printf("rec start : 0x%x, end0x%x, size(byte):0x%x\n",Rec_AC97_BUF, End_Rec_AC97_BUF, PCM_Size );
//IRQ Initialization
//n/a
printf("Are you ready to record sound via MIC socket on SMDK2450?\n");
printf("Press any key to start record.\n");
getchar();
printf("Recording...\n");
//rAC_GLBCTRL = 0x40C; // PIO Mode On
rAC_GLBCTRL = AC97_MIC_IN_MODE_PIO |AC97_ACLINK_ON|AC97_TRANSFERDATA_EN;
/*
while(1)
{
fullcnt = AC97_FifoCntMICIN(0);
if(fullcnt <8) continue;
//when fifo has more than 8 data, read to memory
for(i=0; i<fullcnt; i++)
{
*(Rec_AC97_BUF++) = rAC_MICDATA;//read by 32bit to play
if(Rec_AC97_BUF == End_Rec_AC97_BUF) break;
}
if(Rec_AC97_BUF == End_Rec_AC97_BUF)
{
break;
}
}
*/
while(1)
{
AC97_Fifoaddr = rAC_MICADDR;
AC97_FifoaddrW = (AC97_Fifoaddr &0xf) ;//fifo index write
AC97_FifoaddrR = (AC97_Fifoaddr &0xf0000) >>16 ;//fifo index read
if( AC97_FifoaddrW > AC97_FifoaddrR)
AC97_FifoaddrR+=16;
emptycnt = AC97_FifoaddrR - AC97_FifoaddrW;
//fullcnt = 16-emptycnt;
{
//printf("read %d, write %d emptycnt%d\n",AC97_FifoaddrR,AC97_FifoaddrW, emptycnt );
}
if(emptycnt>8) continue;//fifo cnt<9 continue.
for(i=0; i<emptycnt; i++)
{
*(Rec_AC97_BUF++) = rAC_MICDATA;
if(Rec_AC97_BUF == End_Rec_AC97_BUF) break;
}
if(Rec_AC97_BUF == End_Rec_AC97_BUF)
{
break;
}
}
rAC_GLBCTRL &= ~AC97_MIC_IN_MODE_PIO; //MIC In Transfer PIO Mode Off
printf("\nEnd of Record!\n");
}
//////////////////////////////////////
//utility
char AC97_FifoEmptyCntPCMOUT(bool bprint)
{
unsigned int AC97_Fifoaddr,AC97_FifoaddrR,AC97_FifoaddrW, AC97_Stat;
char emptycnt;
char *pstr1, *pstr2;
AC97_Fifoaddr = rAC_PCMADDR;
AC97_FifoaddrW = (AC97_Fifoaddr &0xf00) >>8 ;//fifo index write
AC97_FifoaddrR = (AC97_Fifoaddr &0xf000000) >>24 ;//fifo index read
if( AC97_FifoaddrW > AC97_FifoaddrR)
AC97_FifoaddrR+=16;
emptycnt = AC97_FifoaddrR - AC97_FifoaddrW;
if(bprint)
{
AC97_Stat=rAC_GLBSTAT;
pstr1 = ( AC97_Stat&AC97_PCM_OUT_UNDERRUN )?" pcm out underrun requested\n" : " ";
pstr2 = ( AC97_Stat&AC97_PCM_OUT_THRESHOLD )?" pcm out threshold requested\n" : " ";
printf(" read %d, write %d emptycnt%d\n%s%s\n",AC97_FifoaddrR,AC97_FifoaddrW, emptycnt,
pstr1, pstr2);
}
return emptycnt;
}
char AC97_FifoEmptyCntPCMIN(bool bprint)
{
unsigned int AC97_Fifoaddr,AC97_FifoaddrR,AC97_FifoaddrW, AC97_Stat;
char emptycnt;
char *pstr1, *pstr2;
AC97_Fifoaddr = rAC_PCMADDR;
AC97_FifoaddrW = (AC97_Fifoaddr &0xf) ;//fifo index write
AC97_FifoaddrR = (AC97_Fifoaddr &0xf0000) >>16 ;//fifo index read
if( AC97_FifoaddrW > AC97_FifoaddrR)
AC97_FifoaddrR+=16;
emptycnt = AC97_FifoaddrR - AC97_FifoaddrW;
if(bprint)
{
AC97_Stat=rAC_GLBSTAT;
pstr1 = ( AC97_Stat&AC97_PCM_IN_OVERRUN )?" pcm in overrun requested\n" : " ";
pstr2 = ( AC97_Stat&AC97_PCM_IN_THRESHOLD )?" pcm in threshold requested\n" : " ";
printf(" read %d, write %d emptycnt%d\n%s%s\n",AC97_FifoaddrR,AC97_FifoaddrW, emptycnt,
pstr1, pstr2);
}
return emptycnt;
}
char AC97_FifoEmptyCntMICIN(bool bprint)
{
unsigned int AC97_Fifoaddr,AC97_FifoaddrR,AC97_FifoaddrW, AC97_Stat;
char emptycnt;
char *pstr1, *pstr2;
AC97_Fifoaddr = rAC_MICADDR;
AC97_FifoaddrW = (AC97_Fifoaddr &0xf) ;//fifo index write
AC97_FifoaddrR = (AC97_Fifoaddr &0xf0000) >>16 ;//fifo index read
if( AC97_FifoaddrW > AC97_FifoaddrR)
AC97_FifoaddrR+=16;
emptycnt = AC97_FifoaddrR - AC97_FifoaddrW;
if(bprint)
{
AC97_Stat=rAC_GLBSTAT;
pstr1 = ( AC97_Stat&AC97_MIC_IN_OVERRUN )?" mic in overrun requested\n" : " ";
pstr2 = ( AC97_Stat&AC97_MIC_IN_THRESHOLD )?" mic in threshold requested\n" : " ";
printf(" read %d, write %d emptycnt%d\n%s%s\n",AC97_FifoaddrR,AC97_FifoaddrW, emptycnt,
pstr1, pstr2);
}
return emptycnt;
}
//reflect current fulled fifo count.
char AC97_FifoCntMICIN(bool bprint)
{
unsigned int AC97_Fifoaddr,AC97_FifoaddrR,AC97_FifoaddrW, AC97_Stat;
char emptycnt, fullcnt;
char *pstr1, *pstr2;
AC97_Fifoaddr = rAC_MICADDR;
AC97_FifoaddrW = (AC97_Fifoaddr &0xf) ;//fifo index write
AC97_FifoaddrR = (AC97_Fifoaddr &0xf0000) >>16 ;//fifo index read
if( AC97_FifoaddrW > AC97_FifoaddrR)
AC97_FifoaddrR+=16;
emptycnt = AC97_FifoaddrR - AC97_FifoaddrW;
fullcnt = 16-emptycnt;
if(bprint)
{
AC97_Stat=rAC_GLBSTAT;
pstr1 = ( AC97_Stat&AC97_MIC_IN_OVERRUN )?" mic in overrun requested\n" : " ";
pstr2 = ( AC97_Stat&AC97_MIC_IN_THRESHOLD )?" mic in threshold requested\n" : " ";
printf(" read %d, write %d emptycnt%d\n%s%s\n",AC97_FifoaddrR,AC97_FifoaddrW, emptycnt,
pstr1, pstr2);
}
return fullcnt;
}
//////////////////////////////////////////
// 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(g_test) printf("%x", Play_AC97_BUF);
if(Play_AC97_BUF == End_AC97_BUF)
{
printf("end");
break;
}
}
}
else if (AC97_Stat & AC97_PCM_OUT_UNDERRUN)
{
printf("underrun occured\n");
AC97_FifoEmptyCntPCMOUT(1);
rAC_GLBCTRL &= ~AC97_PCM_OUT_UNDERRUN; //PCM Out channel underrun int disable.
}
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_PCMoutIntTest(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)
{
printf("ISR pcm out threshold occured\n");
AC97_FifoEmptyCntPCMOUT(1);
rAC_GLBCTRL &= ~AC97_PCM_OUT_THRESHOLD; //PCM Out channel threshold INT disable
}
else
if (AC97_Stat & AC97_PCM_OUT_UNDERRUN)
{
printf("ISR pcm out underrun occured\n");
AC97_FifoEmptyCntPCMOUT(1);
rAC_GLBCTRL &= ~AC97_PCM_OUT_UNDERRUN; //PCM Out channel underrun int disable.
}
rSUBSRCPND=(BIT_SUB_AC97);
ClearPending(BIT_WDT_AC97);
rINTSUBMSK &= ~(BIT_SUB_AC97);
rINTMSK &= ~(BIT_WDT_AC97);
}
void __irq Irq_AC97_PCMin(void)
{
unsigned int AC97_Stat, i;
static unsigned long cnt=0;
rINTMSK |=(BIT_WDT_AC97);
rINTSUBMSK|=(BIT_SUB_AC97);
cnt++;
if((cnt%2000)==0)
WrUTXH0('.');
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
AC97_In_INT_Exit =1;
cnt = 0;
}
rSUBSRCPND=(BIT_SUB_AC97);
ClearPending(BIT_WDT_AC97);
rINTSUBMSK &= ~(BIT_SUB_AC97);
rINTMSK &= ~(BIT_WDT_AC97);
}
void __irq Irq_AC97_PCMinIntTest(void)
{
unsigned int AC97_Stat, i;
static unsigned long cnt=0;
rINTMSK |=(BIT_WDT_AC97);
rINTSUBMSK|=(BIT_SUB_AC97);
AC97_Stat = rAC_GLBSTAT;
if (AC97_Stat & AC97_PCM_IN_THRESHOLD)
{
printf("ISR pcm in threshold occured\n");
AC97_FifoEmptyCntPCMIN(1);
rAC_GLBCTRL &= ~AC97_PCM_IN_THRESHOLD; //PCM In channel threshold INT disable
}
else if (AC97_Stat & AC97_PCM_IN_OVERRUN)
{
printf("ISR pcm in overrun occured\n");
AC97_FifoEmptyCntPCMIN(1);
rAC_GLBCTRL &= ~AC97_PCM_IN_OVERRUN; //PCM In channel overrun int disable
}
rSUBSRCPND=(BIT_SUB_AC97);
ClearPending(BIT_WDT_AC97);
rINTSUBMSK &= ~(BIT_SUB_AC97);
rINTMSK &= ~(BIT_WDT_AC97);
}
void __irq Irq_AC97_MICin(void)
{
unsigned int AC97_Stat, i;
rINTMSK |=(BIT_WDT_AC97);
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
AC97_In_INT_Exit =1;
}
rSUBSRCPND=(BIT_SUB_AC97);
ClearPending(BIT_WDT_AC97);
rINTSUBMSK &= ~(BIT_SUB_AC97);
rINTMSK &= ~(BIT_WDT_AC97);
}
void __irq Irq_AC97_MICinIntTest(void)
{
unsigned int AC97_Stat, i;
static unsigned long cnt=0;
rINTMSK |=(BIT_WDT_AC97);
rINTSUBMSK|=(BIT_SUB_AC97);
AC97_Stat = rAC_GLBSTAT;
if (AC97_Stat & AC97_MIC_IN_THRESHOLD)
{
printf("ISR mic in threshold occured\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -