⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcm.c

📁 samsung 最新芯片2450 的测试程序.
💻 C
📖 第 1 页 / 共 5 页
字号:
	{
		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 + -