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

📄 pcm.c

📁 samsung 最新芯片2450 的测试程序.
💻 C
📖 第 1 页 / 共 5 页
字号:
		rINTMSK2|=(BIT_PCM0);
	}
	else
	{
		rPCM_CTL1 = 0;		
		rPCM_CLKCTL1 = 0;					
		rINTMSK2|=(BIT_PCM1);
	}
		
	PCM_DisableInt();   	
	printf("\nEnd of Play!\n");
}


//memory : 16bit stereo continous expected(16bit mono left, first 16bit is available to play)
void PCM_PCMOutInt2(unsigned int uBufferAddr, unsigned int uPcmSize)
{
	unsigned int uSclkDiv, uSyncDiv, uSclkSel;
	unsigned int uTxMsbPos, uRxMsbPos;
	bool bret;
	
	
	//printf("\nListen to Sound via Speak Out Connector.\n");
	//printf("Press any key to play.\n");
    //getchar();	
	
	//init variable
	g_PcmPlayDone =0;
	g_uPcmBuffer32 = (unsigned int *) uBufferAddr;
	g_uPcmEndBuffer32 = g_uPcmBuffer32 + uPcmSize/4;
    
	//IRQ Initialization
	PCM_ISRInit();  
	PCM_ClearInt();
	PCM_SetInt(TXFIFO_ALMOST_EMPTY);
	PCM_EnableInt();

	//presetting
	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.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	;
	}
	
	//setting
	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);		
	}


	//playing
	while(1)
	{
	 	if(g_PcmPlayDone)
			break;	
	}
	
	
	//stop   	
	if(g_oPCMState.PCMPort == PCM_PORT0)   	
	{
		rPCM_CTL0 = 0;		
		rPCM_CLKCTL0 = 0;		
	}
	else
	{
		rPCM_CTL1 = 0;		
		rPCM_CLKCTL1 = 0;
	}
	PCM_DisableInt();	
	PCM_ISRDeInit();
	printf("\nEnd of Play!\n");
}


void PCM_ISRInit(void)
{
	if(g_oPCMState.PCMPort == PCM_PORT0)	
	{
		ClearPending2(BIT_PCM0);	
		pISR_PCM0 = (unsigned)Isr_PCM_PCMOut2;	
	   	rINTMSK2=~(BIT_PCM0);					
	}
	else
	{
		ClearPending2(BIT_PCM1);	
		pISR_PCM1 = (unsigned)Isr_PCM_PCMOut2;	
	   	rINTMSK2=~(BIT_PCM1);							
	}	
}

void PCM_ISRDeInit(void)
{
	if(g_oPCMState.PCMPort == PCM_PORT0)	
	{
		rINTMSK2|=(BIT_PCM0);					
	}
	else
	{
		rINTMSK2|=(BIT_PCM1);							
	}	
}


void PCM_ClearInt(void)
{
	if(g_oPCMState.PCMPort == PCM_PORT0)
		rPCM_CLRINT0 = CLRINT;
	else
		rPCM_CLRINT1 = CLRINT;
}

void PCM_EnableInt(void)
{

	if(g_oPCMState.PCMPort == PCM_PORT0)	
		rPCM_IRQ_CTL0 |= EN_IRQ_TO_ARM;
	else
		rPCM_IRQ_CTL1 |= EN_IRQ_TO_ARM;
}

void PCM_DisableInt(void)
{		
	if(g_oPCMState.PCMPort == PCM_PORT0)	
		rPCM_IRQ_CTL0 &= ~EN_IRQ_TO_ARM;
	else
		rPCM_IRQ_CTL1 &= ~EN_IRQ_TO_ARM;
}


void PCM_SetInt(unsigned int ePcmInt)
{		
	if(g_oPCMState.PCMPort == PCM_PORT0)	
		rPCM_IRQ_CTL0 = (rPCM_IRQ_CTL0 & EN_IRQ_TO_ARM) | ePcmInt;
	else
		rPCM_IRQ_CTL1 = (rPCM_IRQ_CTL1 & EN_IRQ_TO_ARM) | ePcmInt;
}




//input : 
//	enable 1 : selected clock path open 
//		   0 : selected clock path close
void PCM_SelClkSrc(unsigned char ePort, unsigned char eClkSrc, bool enable)
{
	//port0,1
	if(eClkSrc == PCM_PCLK)
	{
		if(enable)
			rPCLKCON |= (1<<19); // PCLK bus block of pcm(0&1) enable
		else
			rPCLKCON &= ~(1<<19);// PCLK bus block of pcm(0&1) disable
	}		
	else//PCM_PCMCDCLK
	{
		if(enable)
		{
			printf("extclk clock gate open, port %d\n", ePort);
			if(ePort == PCM_PORT0) 		rSCLKCON |= (1<<17); // bus block of pcm0 EXT Codec Clock enable
			else if(ePort == PCM_PORT1)	rSCLKCON |= (1<<18); // bus block of pcm0 EXT Codec Clock enable			
		}
		else
		{
			printf("extclk clock gate close, port %d\n", ePort);
			if(ePort == PCM_PORT0) 		rSCLKCON &= ~(1<<17); // bus block of pcm0 EXT Codec Clock disable
			else if(ePort == PCM_PORT1)	rSCLKCON &= ~(1<<18); // bus block of pcm0 EXT Codec Clock disable			
		}
	}		
}


//return : false - with current configuration impossible to make.
bool PCM_GetClkValAndClkDir(unsigned int* uSclkDiv, unsigned int* uSyncDiv)
{
#if 0

	double dTmpVal, dVclkSrc;
	double uTemp0,uTemp1,uTemp2,uTemp3,uTemp4,uTemp5;

	if(g_oPCMState.PCMClkSrc == PCM_PCMCDCLK)
		dVclkSrc = (double)g_oPCMState.EXTCDCLKFreq;			//should be changed according to your system clock condition	
	else if(g_oPCMState.PCMClkSrc == PCM_PCLK)
		dVclkSrc = (double)PCLK;			//should be changed according to your system clock condition

	uTemp1 = 1 / dVclkSrc;
	uTemp2 = 1 /(double) g_oPCMState.PCMSClk;
	uTemp3 = (18 * (double) g_oPCMState.PCMSClk) / 16;
	uTemp4 = 1 / (uTemp1 + uTemp2);
	
	// Calculate SCLK_DIV for PCMSCLK
	if (g_oPCMState.PCMMSBPosition  == DURING_PCMSYNC_HIGH)
		dTmpVal = dVclkSrc/(double)(2*g_oPCMState.PCMSClk) - 1;				//PCMSCLK = dvclksrc / (2 * usclkDiv +1)
	else if   (g_oPCMState.PCMMSBPosition  == AFTER_PCMSYNC_HIGH)
		//dTmpVal = dVclkSrc/(double)(2*(g_oPCMState.PCMSClk)) - 1;			//PCMSCLK = dvclksrc / (2 * usclkDiv +1)	
		dTmpVal = dVclkSrc/(double)(2*(uTemp3)) - 1;						//PCMSCLK = dvclksrc / (2 * usclkDiv +1)	

	dTmpVal = (dTmpVal+0.5)*10;
	*uSclkDiv = (int)(dTmpVal/10.0);

	// Calculate SYNC_DIV for PCMSYNC
	
	if (g_oPCMState.PCMMSBPosition  == DURING_PCMSYNC_HIGH)
		dTmpVal = (double) g_oPCMState.PCMSClk/(double)(g_oPCMState.PCMSync) - 1;		//PCMSYNC = PCMSCLK / (SYNC_DIV + 1)
	else if   (g_oPCMState.PCMMSBPosition  == AFTER_PCMSYNC_HIGH)
		//dTmpVal = (double) g_oPCMState.PCMSCLK/(double)( 128000/17) -1;
		dTmpVal = (double) uTemp3/(double)( g_oPCMState.PCMSync) -1;
	

	//dTmpVal = (double)(g_oPCMState.PCMSCLK)/(double)(g_oPCMState.PCM_FS) - 1;
	dTmpVal = (dTmpVal+0.5)*10;
	*uSyncDiv = (int)(dTmpVal/10.0);
#else
/*		double dTmpVal, dVclkSrc;

//	extern u32		g_MPLL, g_ARMCLK, g_HCLK, g_PCLK, g_MCLK;
	
	if(g_oPCMState.PCMClkSrc == PCM_PCMCDCLK)
		dVclkSrc = 512000;	
	else if(g_oPCMState.PCMClkSrc == PCM_PCLK)
		dVclkSrc = g_PCLK;	//should be changed according to your system clock condition
	
	dTmpVal = dVclkSrc/(double)(2*g_oPCMState.PCMSCLK);
	if (g_oPCMState.PCMMSBPosition == DURING_PCMSYNC_HIGH)
		dTmpVal = (dTmpVal)*10;					
	else if   (g_oPCMState.PCMMSBPosition == AFTER_PCMSYNC_HIGH)
		dTmpVal = (dTmpVal + 0.5)*10;
	*uSclkDiv = (int)(dTmpVal/10.0) - 1;

	if (g_oPCMState.PCMMSBPosition == DURING_PCMSYNC_HIGH)
		dTmpVal = g_oPCMState.PCMSCLK/(double)(g_oPCMState.PCM_FS);		
	else if   (g_oPCMState.PCMMSBPosition == AFTER_PCMSYNC_HIGH)
		dTmpVal = g_oPCMState.PCMSCLK/(double)(g_oPCMState.PCM_FS) + 1;
	dTmpVal = (dTmpVal-0.5)*10;
	*uSyncDiv = (int)(dTmpVal/10.0);
*/
	//for after sync, 16 fs is not allowed.

	double dTmpVal, dVclkSrc;

	if(g_oPCMState.PCMClkSrc == PCM_PCMCDCLK)
		dVclkSrc = (double)g_oPCMState.EXTCDCLKFreq;			//should be changed according to your system clock condition	
	else if(g_oPCMState.PCMClkSrc == PCM_PCLK)
		dVclkSrc = (double)PCLK;			//should be changed according to your system clock condition

	// Calculate SCLK_DIV for PCMSCLK
	dTmpVal = dVclkSrc/(double)(2*g_oPCMState.PCMSClk) - 1;				//PCMSCLK = dvclksrc / (2 * usclkDiv +1)
	if(dTmpVal<0 || dTmpVal>511)return 0;
	dTmpVal = (dTmpVal+0.5)*10;
	*uSclkDiv = (int)(dTmpVal/10.0);

	// Calculate SYNC_DIV for PCMSYNC
	dTmpVal = (double) g_oPCMState.PCMSClk/(double)(g_oPCMState.PCMSync) - 1;		//PCMSYNC = PCMSCLK / (SYNC_DIV + 1)
	if(dTmpVal<0 || dTmpVal>511)return 0;
	dTmpVal = (dTmpVal+0.5)*10;
	*uSyncDiv = (int)(dTmpVal/10.0);

	return 1;
#endif






 }


///////////////////////////////////////////////
void __irq Isr_PCM_PCMIn_DMADone(void)
{
    ClearPending(BIT_DMA);	
	
	printf("\nPCM In DMA Done.\n");
	
	rSUBSRCPND=(BIT_SUB_DMA2);
	               
    g_PcmRecDone = 1;
}

void __irq Isr_PCM_PCMOut_DMADone(void)
{
	rINTSUBMSK=~(BIT_SUB_DMA2);
	rINTMSK = ~(BIT_DMA);
	rSUBSRCPND=(BIT_SUB_DMA1);      
     ClearPending(BIT_DMA);	
	
	printf("\n~~~");

	g_PcmPlayDone=1;

	rINTMSK |= (BIT_DMA);
	rINTSUBMSK |=(BIT_SUB_DMA2);

}


void __irq Isr_PCM_Interrupt(void)
{
		unsigned int i, uPcmFifoStat; 
		int testreg;

	if(g_oPCMState.PCMPort == PCM_PORT0)	
	{		
		rINTMSK2|=(BIT_PCM0);
		
		g_pcmirqstat[g_interrupt_cnt].irqstat1 = rPCM_IRQ_STAT0;
		
		if(rPCM_IRQ_CTL0 & RXFIFO_FULL) testreg = rPCM_RXFIFO0;	
		else if(rPCM_IRQ_CTL0 & RXFIFO_ALMOST_FULL) testreg = rPCM_RXFIFO0;	
		if(rPCM_IRQ_CTL0 & RXFIFO_EMPTY) rPCM_RXFIFO0=0x1111;	
		else if(rPCM_IRQ_CTL0 & RXFIFO_ALMOST_EMPTY) rPCM_RXFIFO0=0x1111;	
		
//		if(rPCM_IRQ_CTL0 & TXFIFO_FULL) testreg = rPCM_TXFIFO0;	
//		else if(rPCM_IRQ_CTL0 & TXFIFO_ALMOST_FULL) testreg = rPCM_TXFIFO0;			
		if(rPCM_IRQ_CTL0 & TXFIFO_EMPTY) rPCM_TXFIFO0=0x1111;	
		else if(rPCM_IRQ_CTL0 & TXFIFO_ALMOST_EMPTY) rPCM_TXFIFO0=0x1111;			
		
		
		PCM_ClearInt();		
		g_pcmirqstat[g_interrupt_cnt].irqstat2 = rPCM_IRQ_STAT0;
		g_interrupt_cnt++;
		
		
		printf("interrupt occured\n");		
		
		if(g_interrupt_cnt>=PCM_IRQ_STAT_MAX) PCM_DisableInt();		
		ClearPending2(BIT_PCM0);		
		rINTMSK2&=~(BIT_PCM0);
	}
	else
	{
		rINTMSK2|=(BIT_PCM1);
		
		g_pcmirqstat[g_interrupt_cnt].irqstat1 = rPCM_IRQ_STAT1;
		
		if(rPCM_IRQ_CTL1 & RXFIFO_FULL) testreg = rPCM_RXFIFO1;	
		else if(rPCM_IRQ_CTL1 & RXFIFO_ALMOST_FULL) testreg = rPCM_RXFIFO1;	
		if(rPCM_IRQ_CTL1 & RXFIFO_EMPTY) rPCM_RXFIFO1=0x1111;	
		else if(rPCM_IRQ_CTL1 & RXFIFO_ALMOST_EMPTY) rPCM_RXFIFO1=0x1111;	
		
//		if(rPCM_IRQ_CTL1 & TXFIFO_FULL) testreg = rPCM_TXFIFO1;	
//		else if(rPCM_IRQ_CTL1 & TXFIFO_ALMOST_FULL) testreg = rPCM_TXFIFO1;			
		if(rPCM_IRQ_CTL1 & TXFIFO_EMPTY) rPCM_TXFIFO1=0x1111;	
		else if(rPCM_IRQ_CTL1 & TXFIFO_ALMOST_EMPTY) rPCM_TXFIFO1=0x1111;	
		
		
		PCM_ClearInt();		
		g_pcmirqstat[g_interrupt_cnt].irqstat2 = rPCM_IRQ_STAT1;
		g_interrupt_cnt++;
		
		printf("interrupt occured\n");				
		
		if(g_interrupt_cnt>=PCM_IRQ_STAT_MAX) PCM_DisableInt();		
		ClearPending2(BIT_PCM1);		
		rINTMSK2&=~(BIT_PCM1);	
	}
}



void __irq Isr_PCM_InterruptTEST(void)
{
		unsigned int i, uPcmFifoStat; 
		int testreg;

	if(g_oPCMState.PCMPort == PCM_PORT0)	
	{		
		rINTMSK2|=(BIT_PCM0);
		
		g_pcmirqstat[g_interrupt_cnt].irqstat1 = rPCM_IRQ_STAT0;
		
		if(rPCM_IRQ_CTL0 & RXFIFO_FULL) testreg = rPCM_RXFIFO0;	
		else if(rPCM_IRQ_CTL0 & RXFIFO_ALMOST_FULL) testreg = rPCM_RXFIFO0;	
		if(rPCM_IRQ_CTL0 & RXFIFO_EMPTY) rPCM_RXFIFO0=0x1111;	
		else if(rPCM_IRQ_CTL0 & RXFIFO_ALMOST_EMPTY) rPCM_RXFIFO0=0x1111;	
		
		if(rPCM_IRQ_CTL0 & TXFIFO_FULL) te

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -