📄 pcm.c
字号:
{
ClearPending2(BIT_PCM0);
if(fn_extra==NULL) pISR_PCM0 = (unsigned)Isr_PCM_Interrupt;
else pISR_PCM0 = (unsigned)Isr_PCM_InterruptTEST;
rINTMSK2=~(BIT_PCM0);
}
else
{
ClearPending2(BIT_PCM1);
if(fn_extra==NULL) pISR_PCM1 = (unsigned)Isr_PCM_Interrupt;
else pISR_PCM1 = (unsigned)Isr_PCM_InterruptTEST;
rINTMSK2=~(BIT_PCM1);
}
//IRQ Setting
PCM_ClearInt();
PCM_SetInt(RXFIFO_ERROR_OVERFLOW);
PCM_EnableInt();
pISR_DMA = (unsigned)Isr_PCM_PCMIn_DMADone;
ClearPending(BIT_DMA);
rSUBSRCPND=(BIT_SUB_DMA2);
rINTMSK = ~(BIT_DMA);
rINTSUBMSK=~(BIT_SUB_DMA2);
//DMA setting
PCM_PCMInDMASetting(uRecBufferAddr, uPcmSize);
printf("Supply Sound to PCM CODEC via Line In Connector.\n");
printf("Press any key to record.\n");
if(fn_extra==NULL)getchar();
printf("Recording...\n");
//dma start
g_PcmRecDone = 0;
rDMASKTRIG2 = (0<<2) + (1<<1) + 0; //No-stop, DMA2 channel on, No-sw trigger
//Enable
//for dma rxfifo dipstick is don't care
*rPCM_CTL |= (RXFIFO_DIPSTICK(0x8) | PCM_RX_DMA_EN | PCM_RXFIFO_EN );//fifo flush, dma enable
*rPCM_CLKCTL |= PCM_SCLK_EN;
*rPCM_CTL |= PCM_PCM_ENABLE;
while(g_PcmRecDone ==0)
{
printf(".");
Delay(1000);
uChar = Uart_GetKey();
if( (uChar == 'x') | (uChar == 'X'))
break;
if(cnt == 2 && fn_extra!=NULL)
{
bret = fn_extra();
break;
}
cnt++;
}
ClearPending(BIT_DMA);
rSUBSRCPND=(BIT_SUB_DMA2);
rDMASKTRIG2 = (1<<2); //DMA2 stop
rINTMSK |= (BIT_DMA);
rINTSUBMSK |=(BIT_SUB_DMA2);
//pcm in dma finish
*rPCM_CTL&= ~PCM_RX_DMA_EN;
*rPCM_CTL&= ~(PCM_SCLK_EN|PCM_PCM_ENABLE|PCM_RXFIFO_EN);
PCM_DisableInt();
printf("\nEnd of Record!\n");
return bret;
}
bool PCM_PCMOutDMA(unsigned int uPlayBufferAddr, unsigned int uPcmSize, bool (*fn_extra)(void))
{
unsigned char uChar;
unsigned int *rPCM_CTL=(g_oPCMState.PCMPort==0)?(unsigned int *)&rPCM_CTL0:(unsigned int *)&rPCM_CTL1;
unsigned int *rPCM_CLKCTL=(g_oPCMState.PCMPort==0)?(unsigned int *)&rPCM_CLKCTL0:(unsigned int *)&rPCM_CLKCTL1;
int cnt=0;
bool bret = TRUE;
g_PcmPlayDone=0;
//IRQ Initialization
g_interrupt_cnt=0;
if(g_oPCMState.PCMPort == PCM_PORT0)
{
ClearPending2(BIT_PCM0);
if(fn_extra==NULL) pISR_PCM0 = (unsigned)Isr_PCM_Interrupt;
else pISR_PCM0 = (unsigned)Isr_PCM_InterruptTEST;
rINTMSK2=~(BIT_PCM0);
}
else
{
ClearPending2(BIT_PCM1);
if(fn_extra==NULL) pISR_PCM1 = (unsigned)Isr_PCM_Interrupt;
else pISR_PCM1 = (unsigned)Isr_PCM_InterruptTEST;
rINTMSK2=~(BIT_PCM1);
}
//IRQ Setting
PCM_ClearInt();
PCM_SetInt(TXFIFO_ERROR_STARVE); //underrun
PCM_EnableInt();
pISR_DMA= (unsigned)Isr_PCM_PCMOut_DMADone;
//DMA setting
PCM_PCMOutDMASetting(uPlayBufferAddr, uPcmSize);
printf("\nListen to Sound via Speak Out Connector.\n");
printf("Press any key to play.\n");
if(fn_extra==NULL) getchar();
rDMASKTRIG1 = (0<<2) + (1<<1) + (1<<0); //No-stop[2], DMA1 channel On[1], No-sw trigger[0]
//Enable
*rPCM_CTL |= (TXFIFO_DIPSTICK(0x8) | PCM_TX_DMA_EN | PCM_TXFIFO_EN );//fifo flush, dma enable
PCM_TXFIFOwaitTillFULL();//wait till fifo is almost full
*rPCM_CLKCTL |= PCM_SCLK_EN;
*rPCM_CTL |= PCM_PCM_ENABLE;
printf("\nIf you want to exit, Press the 'x' key.\n");
while(g_PcmPlayDone==0)
{
printf(".");
Delay(1000);
uChar = Uart_GetKey();
if( (uChar == 'x') | (uChar == 'X')) break;
//else if ( (uChar == 's' )| (uChar =='S') ) AC97_CodecCmdManually();
if(cnt == 2 && fn_extra!=NULL)
{
bret = fn_extra();
break;
}
cnt++;
}
ClearPending(BIT_DMA);
rSUBSRCPND=(BIT_SUB_DMA1);
rDMASKTRIG1 = (1<<2); //DMA1 stop
rINTMSK |= (BIT_DMA);
rINTSUBMSK |=(BIT_SUB_DMA1);
//pcm out dma finish
*rPCM_CTL&= ~PCM_TX_DMA_EN;
//PCM_TXFIFOwaitTillEmpty();
*rPCM_CTL&= ~(PCM_SCLK_EN|PCM_PCM_ENABLE|PCM_TXFIFO_EN);
printf("\nEnd of Play!\n");
return bret;
}
//uPcmSize : byte size
void PCM_PCMInInt(unsigned int uRecBufferAddr, unsigned int uPcmSize)
{
unsigned int *rPCM_CTL=(g_oPCMState.PCMPort==0)?(unsigned int *)&rPCM_CTL0:(unsigned int *)&rPCM_CTL1;
unsigned int *rPCM_CLKCTL=(g_oPCMState.PCMPort==0)?(unsigned int *)&rPCM_CLKCTL0:(unsigned int *)&rPCM_CLKCTL1;
g_uPcmRecBuffer = (unsigned short *) uRecBufferAddr;
g_uPcmEndRecBuffer = g_uPcmRecBuffer + uPcmSize/2;
//IRQ Initialization
if(g_oPCMState.PCMPort == PCM_PORT0)
{
ClearPending2(BIT_PCM0);
pISR_PCM0 = (unsigned)Isr_PCM_PCMIn;
rINTMSK2=~(BIT_PCM0);
}
else
{
ClearPending2(BIT_PCM1);
pISR_PCM1 = (unsigned)Isr_PCM_PCMIn;
rINTMSK2=~(BIT_PCM1);
}
printf("Supply Sound to PCM CODEC via Line In Connector.\n");
printf("Press any key to record.\n");
getchar();
printf("Recording...\n");
g_PcmRecDone =0;
PCM_ClearInt();
PCM_SetInt(RXFIFO_ALMOST_FULL);//rx fifo not empty, then read as soon as possible.
PCM_EnableInt();
//Enable
*rPCM_CTL |= (RXFIFO_DIPSTICK(0x20) | PCM_RXFIFO_EN );//fifo flush, dma enable
*rPCM_CLKCTL |= PCM_SCLK_EN;
*rPCM_CTL |= PCM_PCM_ENABLE;
while(1)
{
if(g_PcmRecDone) break;
}
//Finish
*rPCM_CTL&= ~(PCM_SCLK_EN|PCM_PCM_ENABLE|PCM_RXFIFO_EN);
if(g_oPCMState.PCMPort == PCM_PORT0) rINTMSK2|=(BIT_PCM0);
else rINTMSK2|=(BIT_PCM1);
PCM_DisableInt();
printf("\nEnd of Record!\n");
}
bool PCM_PCMInOutDMA(unsigned int uPlayBufferAddr, unsigned int uRecBufferAddr, unsigned int uPcmSize, bool (*fn_extra)(void))
{
unsigned char uChar;
int cnt=0;
bool bret = TRUE;
unsigned int *rPCM_CTL=(g_oPCMState.PCMPort==0)?(unsigned int *)&rPCM_CTL0:(unsigned int *)&rPCM_CTL1;
unsigned int *rPCM_CLKCTL=(g_oPCMState.PCMPort==0)?(unsigned int *)&rPCM_CLKCTL0:(unsigned int *)&rPCM_CLKCTL1;
//IRQ Initialization
g_interrupt_cnt=0;
if(g_oPCMState.PCMPort == PCM_PORT0)
{
ClearPending2(BIT_PCM0);
pISR_PCM0 = (unsigned)Isr_PCM_Interrupt;
rINTMSK2=~(BIT_PCM0);
}
else
{
ClearPending2(BIT_PCM1);
pISR_PCM1 = (unsigned)Isr_PCM_Interrupt;
rINTMSK2=~(BIT_PCM1);
}
//IRQ Setting
PCM_ClearInt();
PCM_SetInt(TXFIFO_ERROR_STARVE); //underrun
PCM_EnableInt();
pISR_DMA= (unsigned)Isr_PCM_PCMOut_DMADone;
//DMA setting
PCM_PCMInDMASetting(uRecBufferAddr, uPcmSize);
PCM_PCMOutDMASetting(uPlayBufferAddr, uPcmSize);
printf("\nListen to Sound via Speak Out Connector.\n");
printf("Press any key to play.\n");
if(fn_extra==NULL) getchar();
//DMA start
g_PcmPlayDone = 0;
rDMASKTRIG1 = (0<<2) + (1<<1) + (1<<0); //No-stop[2], DMA1 channel On[1], No-sw trigger[0]
g_PcmRecDone = 0;
rDMASKTRIG2 = (0<<2) + (1<<1) + 0; //No-stop, DMA2 channel on, No-sw trigger
//Enable
*rPCM_CTL |= (TXFIFO_DIPSTICK(0x8) | PCM_TX_DMA_EN | PCM_TXFIFO_EN | RXFIFO_DIPSTICK(0x8) | PCM_RX_DMA_EN | PCM_RXFIFO_EN);//fifo flush, dma enable
PCM_TXFIFOwaitTillFULL();//wait till fifo is almost full
*rPCM_CLKCTL |= PCM_SCLK_EN;
*rPCM_CTL |= PCM_PCM_ENABLE;
printf("Press the 'x' key to exit\n");
while(!g_PcmPlayDone | !g_PcmRecDone)
{
printf(".");
Delay(1000);
uChar = Uart_GetKey();
if( (uChar == 'x') | (uChar == 'X')) break;
if(cnt == 2 && fn_extra!=NULL)
{
bret = fn_extra();
break;
}
cnt++;
}
ClearPending(BIT_DMA);
rSUBSRCPND=(BIT_SUB_DMA1);
rDMASKTRIG1 = (1<<2); //DMA1 stop
rINTMSK |= (BIT_DMA);
rINTSUBMSK |=(BIT_SUB_DMA1);
//pcm out dma finish
*rPCM_CTL&= ~(PCM_TX_DMA_EN|PCM_RX_DMA_EN);
//PCM_TXFIFOwaitTillEmpty();
*rPCM_CTL&= ~(PCM_SCLK_EN|PCM_PCM_ENABLE|PCM_TXFIFO_EN|PCM_RXFIFO_EN);
printf("\nEnd of Play!\n");
return bret;
}
//memory : 16bit mono continous expected
void PCM_PCMOutInt(unsigned int uRecBufferAddr, unsigned int uPcmSize)
{
unsigned int uSclkDiv, uSyncDiv, uSclkSel;
unsigned int uTxMsbPos, uRxMsbPos;
bool bret;
if(g_oPCMState.PCMMSBPosition == AFTER_PCMSYNC_HIGH)
{
uTxMsbPos = TX_MSB_POS1;
uRxMsbPos = RX_MSB_POS1;
}
else if(g_oPCMState.PCMMSBPosition == DURING_PCMSYNC_HIGH)
{
uTxMsbPos = TX_MSB_POS0;
uRxMsbPos = RX_MSB_POS0 ;
}
g_PcmPlayDone =0;
g_uPcmRecBuffer = (unsigned short *) uRecBufferAddr;
g_uPcmEndRecBuffer = g_uPcmRecBuffer + uPcmSize/2;
//IRQ Initialization
if(g_oPCMState.PCMPort == PCM_PORT0)
{
ClearPending2(BIT_PCM0);
pISR_PCM0 = (unsigned)Isr_PCM_PCMOut;
rINTMSK2=~(BIT_PCM0);
}
else
{
ClearPending2(BIT_PCM1);
pISR_PCM1 = (unsigned)Isr_PCM_PCMOut;
rINTMSK2=~(BIT_PCM1);
}
//printf("\nListen to Sound via Speak Out Connector.\n");
//printf("Press any key to play.\n");
//getchar();
PCM_ClearInt();
PCM_SetInt(TXFIFO_ALMOST_EMPTY);
PCM_EnableInt();
bret=PCM_GetClkValAndClkDir(&uSclkDiv, &uSyncDiv);
if(!bret)
{
printf("clock can not be made, exit");
return;
}
if(g_oPCMState.PCMClkSrc == PCM_PCLK)
uSclkSel = 1<<18;
else
uSclkSel = 0<<18;
{
double sclk;
double syncclk;
sclk = (double)PCLK /(2*( uSclkDiv+ 1) );
syncclk = sclk /( uSyncDiv+ 1 );
printf("Actural value\n\
Source_Clk : %f PCM_SCLK : %fKHz PCM_Syncclk: %fKHz\n",
(float)PCLK, sclk, syncclk);
}
if(g_oPCMState.PCMPort == PCM_PORT0)
{
rPCM_CLKCTL0 = ( PCM_SCLK_EN | uSclkSel | (uSclkDiv<<9) | (uSyncDiv<<0) ); //PCM Clock Setting
rPCM_CTL0= (TXFIFO_DIPSTICK(0x8) |uTxMsbPos |uRxMsbPos |PCM_TXFIFO_EN|PCM_PCM_ENABLE);//Transfer data enable
}
else
{
rPCM_CLKCTL1 = ( PCM_SCLK_EN | uSclkSel | (uSclkDiv<<9) | (uSyncDiv<<0) );
rPCM_CTL1= (TXFIFO_DIPSTICK(0x8) |uTxMsbPos |uRxMsbPos |PCM_TXFIFO_EN|PCM_PCM_ENABLE);
}
while(1)
{
if(g_PcmPlayDone)
break;
}
if(g_oPCMState.PCMPort == PCM_PORT0)
{
rPCM_CTL0 = 0;
rPCM_CLKCTL0 = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -