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

📄 pcm.c

📁 三星 s3c6400测试代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	u32 i;
	u8 uI2cData[2];
	s32 uI2cDataCount, uI2cPt;

	
	#if (PCM_CODEC_NAME == AK2430)	
		
    uI2cData[0]   = (unsigned char)uAddr;
    uI2cData[1]   = uData;
    uI2cDataCount = 2;
    uI2cPt = 0;

	IICOutp32(rIICCON, (1<<7) | (0<<6) | (1<<5) | (0xf)); //Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
	IICOutp32(rIICSTAT, 0x10);	//IIC bus data output enable(Rx/Tx)
  	IICOutp32(rIICLC, (1<<2)|(1)); 	//Filter enable, 5 clocks SDA output delay    
    
	//Data Write Phase
	IICOutp32(rIICDS, uSlaveAddr); //0xa0
    IICOutp32(rIICSTAT, 0xf0);      
    
    while(uI2cDataCount != -1)
    {
    	if(IICInp32(rIICCON)& 0x10)
    	{                  
       		
       		if((uI2cDataCount--)==0)
            {
            	IICOutp32(rIICSTAT, 0xd0);	//stop MasTx condition 
                IICOutp32(rIICCON, 0xaf);   //resumes IIC operation.
                
                Delay(1);  //wait until stop condtion is in effect.
                break;    
            }

       		IICOutp32(rIICDS, uI2cData[uI2cPt++]); 
             
            for(i=0;i<10;i++);	//for setup time until rising edge of IICSCL
            IICOutp32(rIICCON, 0xaf); 	//resumes IIC operation.
            
		}      
    }
    
   	IICOutp32(rIICSTAT, 0xd0); 	//Master Tx condition, Stop(Write), Output Enable 
    IICOutp32(rIICCON, 0xaf);	//Resumes IIC operation. 
   	
   	Delay(1);  //Wait until stop condtion is in effect.      

   	#elif (PCM_CODEC_NAME == WM8753)	
	
    uI2cData[0]   = (unsigned char)uAddr;
    uI2cData[1]   = uData;
    uI2cDataCount = 2;
    uI2cPt = 0;

	IICOutp32(rIICCON, (1<<7) | (0<<6) | (1<<5) | (0xf)); //Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
   	IICOutp32(rIICSTAT, 0x10);	//IIC bus data output enable(Rx/Tx)
  	IICOutp32(rIICLC, (1<<2)|(3)); 	//Filter enable, 15 clocks SDA output delay    
    
	//Data Write Phase
	IICOutp32(rIICDS, uSlaveAddr); 	//0xa0
    IICOutp32(rIICSTAT, 0xf0);      
    
    while(uI2cDataCount != -1)
    {
    	if(IICInp32(rIICCON)& 0x10)
    	{                  
       		
       		if((uI2cDataCount--)==0)
            {
            	IICOutp32(rIICSTAT, 0xd0);	//stop MasTx condition 
                IICOutp32(rIICCON, 0xaf);   //resumes IIC operation.
                
                Delay(1);  //wait until stop condtion is in effect.
                break;    
            }

       		IICOutp32(rIICDS, uI2cData[uI2cPt++]); 
             
            for(i=0;i<10;i++);	//for setup time until rising edge of IICSCL
            IICOutp32(rIICCON, 0xaf); 	//resumes IIC operation.
            
		}      
    }
    
   	IICOutp32(rIICSTAT, 0xd0); 	//Master Tx condition, Stop(Write), Output Enable 
    IICOutp32(rIICCON, 0xaf);	//Resumes IIC operation. 
   	
   	Delay(1);  //Wait until stop condtion is in effect.      

	#else
		Assert(0);
    #endif
}


u8 PCM_CODEC_IICRead(u32 uSlaveAddr, u8 uAddr)
{
	u8  uI2cData;
	s32 uI2cDataCount, i;

	#if (PCM_CODEC_NAME== AK2430)
	
    uI2cData  = uAddr;
    uI2cDataCount = 1;

	//Register Address Write Phase
	IICOutp32(rIICCON, (1<<7) | (0<<6) | (1<<5) | (0<<4) | (0xf));//Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
	IICOutp32(rIICSTAT, 0x10); //IIC bus data output enable(Rx/Tx)	
    IICOutp32(rIICLC, (1<<2)|(1)); //Filter enable, 15 clocks SDA output delay    		
   
	IICOutp32(rIICDS, uSlaveAddr);
    IICOutp32(rIICSTAT, 0xf0);	//MasTx,Start 
 
   
    while(uI2cDataCount!=-1)
    {
    	if(IICInp32(rIICCON) & 0x10) 
    	{	//Tx/Rx Interrupt Enable
       		if((uI2cDataCount--)==0)
            {
               	break;                
            }
       			IICOutp32(rIICDS, uI2cData);
            	for(i=0;i<10;i++); 	//for setup time until rising edge of IICSCL
            	IICOutp32(rIICCON, 0xaf);	//resumes IIC operation.	
    	}
    }   
    	
    uI2cDataCount = 1;
    IICOutp32(rIICCON, (1<<7) | (0<<6) | (1<<5) | (0<<4) | (0xf));
    
	//Register Data Read Phase 
	IICOutp32(rIICDS, uSlaveAddr);
	
	IICOutp32(rIICSTAT, 0xb0);	//Master Rx,Start
	
   	while(uI2cDataCount!=-1)
   	{
    	if(IICInp32(rIICCON) & 0x10)	//Interrupt pending 
    	{
       		if((uI2cDataCount--)==0)
            {
            	uI2cData = IICInp32(rIICDS);

            	IICOutp32(rIICSTAT, 0x90);		//Stop MasRx condition 
                IICOutp32(rIICCON, 0xaf);       //Resumes IIC operation.
                
                Delay(1);                    //Wait until stop condtion is in effect.
                //Too long time... 
                //The pending bit will not be set after issuing stop condition.
                break;    
            }

            if((uI2cDataCount)==0)
            	IICOutp32(rIICCON, 0x2f);		//Resumes IIC operation with NOACK. 
            else 
            	IICOutp32(rIICCON, 0xaf);		//Resumes IIC operation with ACK
                
    	}
    }

		
    return  uI2cData;

    #elif (PCM_CODEC_NAME == WM8753)	

    uI2cData  = uAddr;
    uI2cDataCount = 1;

	//Register Address Write Phase
	IICOutp32(rIICCON, (1<<7) | (0<<6) | (1<<5) | (0<<4) | (0xf));//Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
	IICOutp32(rIICSTAT, 0x10); //IIC bus data output enable(Rx/Tx)	
    IICOutp32(rIICLC, (1<<2)|(1)); //Filter enable, 15 clocks SDA output delay    		
   
	IICOutp32(rIICDS, uSlaveAddr);
    IICOutp32(rIICSTAT, 0xf0);	//MasTx,Start 
 
   
    while(uI2cDataCount!=-1)
    {
    	if(IICInp32(rIICCON) & 0x10) 
    	{	//Tx/Rx Interrupt Enable
       		if((uI2cDataCount--)==0)
            {
               	break;                
            }
       			IICOutp32(rIICDS, uI2cData);
            	for(i=0;i<10;i++); 	//for setup time until rising edge of IICSCL
            	IICOutp32(rIICCON, 0xaf);	//resumes IIC operation.	
    	}
    }   
    	
    uI2cDataCount = 1;
    IICOutp32(rIICCON, (1<<7) | (0<<6) | (1<<5) | (0<<4) | (0xf));
    
	//Register Data Read Phase 
	IICOutp32(rIICDS, uSlaveAddr);
	IICOutp32(rIICSTAT, 0xb0);	//Master Rx,Start
	
   	while(uI2cDataCount!=-1)
   	{
    	if(IICInp32(rIICCON) & 0x10)	//Interrupt pending 
    	{
       		if((uI2cDataCount--)==0)
            {
            	uI2cData = IICInp32(rIICDS);

            	IICOutp32(rIICSTAT, 0x90);		//Stop MasRx condition 
                IICOutp32(rIICCON, 0xaf);       //Resumes IIC operation.
                
                Delay(1);                    //Wait until stop condtion is in effect.
                //Too long time... 
                //The pending bit will not be set after issuing stop condition.
                break;    
            }

            if((uI2cDataCount)==0)
            	IICOutp32(rIICCON, 0x2f);		//Resumes IIC operation with NOACK. 
            else 
            	IICOutp32(rIICCON, 0xaf);		//Resumes IIC operation with ACK
                
    	}
    }
		
    return  uI2cData;
		
    #else
		Assert(0);
    #endif
    	
}


void PCM_SelClkSrc(PCM_PORT ePort, PCM_CLKSRC eClkSrc)
{
	u32 uClkSrc, uEpllCon0;

	uClkSrc = Inp32SYSC(0x1C);
	uEpllCon0 = Inp32SYSC(0x14);

	if(ePort == PCM_PORT0)
	{
		if(eClkSrc == PCM_MOUT_EPLL) 
		{
			Outp32SYSC(0x14, uEpllCon0 |(1u<<31));
			Delay(100);
			Outp32SYSC(0x1C, uClkSrc & ~(0x7<<7) |(1<<2));	
		}
		else if (eClkSrc == PCM_DOUT_MPLL) Outp32SYSC(0x1C, uClkSrc & ~(0x7<<7)|(1<<7));
		else if (eClkSrc == PCM_FIN_EPLL) Outp32SYSC(0x1C, uClkSrc & ~(0x7<<7)|(2<<7));
		else if (eClkSrc == PCM_PCMCDCLK) Outp32SYSC(0x1C, uClkSrc & ~(0x7<<7)|(4<<7));
	}
	else if(ePort == PCM_PORT1)
	{
		if(eClkSrc == PCM_MOUT_EPLL) 
		{
			Outp32SYSC(0x14, uEpllCon0 |(1u<<31));
			Delay(100);
			Outp32SYSC(0x1C, uClkSrc & ~(0x7<<10)|(1<<2));
		}
		else if (eClkSrc == PCM_DOUT_MPLL) Outp32SYSC(0x1C, uClkSrc & ~(0x7<<10)|(1<<10));
		else if (eClkSrc == PCM_FIN_EPLL) Outp32SYSC(0x1C, uClkSrc & ~(0x7<<10)|(2<<10));
		else if (eClkSrc == PCM_PCMCDCLK) Outp32SYSC(0x1C, uClkSrc & ~(0x7<<10)|(4<<10));
	}
}


void PCM_GetClkValAndClkDir(u32* uSclkDiv, u32* uSyncDiv, PCM_CLKSRC ePcmClkSrc)
{
	double dTmpVal, dVclkSrc;

	if(ePcmClkSrc == PCM_MOUT_EPLL)
		dVclkSrc = 97700000; 	//should be changed according to your system clock condition
	else if(ePcmClkSrc == PCM_DOUT_MPLL)
		dVclkSrc = 100000000; 	//should be changed according to your system clock condition
	else if(ePcmClkSrc == PCM_FIN_EPLL)
		dVclkSrc = 12000000; 	//should be changed according to your system clock condition
	else if(ePcmClkSrc == PCM_PCMCDCLK)
		dVclkSrc = 512000;	
	else if(ePcmClkSrc == PCM_PCLK)
		dVclkSrc = 25000000;	//should be changed according to your system clock condition
	
	dTmpVal = dVclkSrc/(double)(2*PCMSCLK) - 1;
	dTmpVal = (dTmpVal+0.5)*10;
	*uSclkDiv = (int)(dTmpVal/10.0);

	dTmpVal = PCMSCLK/(double)(PCM_FS) - 1;
	dTmpVal = (dTmpVal+0.5)*10;
	*uSyncDiv = (int)(dTmpVal/10.0);

 }


///////////////////////////////////////////////
void __irq Isr_PCM_PCMIn_DMADone(void)
{
	INTC_Disable(oPcm.m_uNumDma);

	Disp("\nPCM In DMA Done.\n");
	uPcmRecDone = 1;

	DMACH_ClearIntPending(&oPcmDma);
	DMACH_ClearErrIntPending(&oPcmDma);
	INTC_ClearVectAddr();	
}

void __irq Isr_PCM_PCMOut_DMADone(void)
{
	INTC_Disable(oPcm.m_uNumDma);
	DMAC_InitCh(oPcm.m_eDmaUnit, oPcm.m_eDmaCh, &oPcmDma);
	
	DMACH_ClearIntPending(&oPcmDma);
	DMACH_ClearErrIntPending(&oPcmDma);
	INTC_ClearVectAddr();	

	Disp("\n~~~");

	INTC_Enable(oPcm.m_uNumDma);

	DMACH_Setup(oPcm.m_eDmaCh, 0x0, (u32)PCM_REC_BUF, false, oPcm.m_uPcmRxFifoAddr, true, HWORD, PCM_REC_LEN/2, HANDSHAKE, MEM, oPcm.m_eDreqSrc , SINGLE, &oPcmDma);
	DMACH_Start(&oPcmDma);

}

void __irq Isr_PCM_PCMIn(void)
{
	u32 i, uPcmFifoStat; 

	INTC_Disable(oPcm.m_uNumInt);

	INTC_ClearVectAddr();
	PCM_ClearInt();
	
	uPcmFifoStat = PCMInp32(rPCMFIFOSTAT);
		
	for(i=0; i< ((uPcmFifoStat & 0x3f0)>>4); i++)
	{
		*(uPcmRecBuffer++) = (u16) PCMInp32(rPCMRXFIFO);		

		if(uPcmRecBuffer ==uPcmEndRecBuffer)
		break;	
	}			

	if(uPcmRecBuffer ==uPcmEndRecBuffer)
		uPcmRecDone=1;
			
	INTC_Enable(oPcm.m_uNumInt);

}

void __irq Isr_PCM_PCMOut(void)
{
	u32 i, uPcmFifoStat; 

	INTC_Disable(oPcm.m_uNumInt);

	INTC_ClearVectAddr();
	PCM_ClearInt();
	
	uPcmFifoStat = PCMInp32(rPCMFIFOSTAT);
		
	for(i=0; i< (32-((uPcmFifoStat & 0xfc000)>>14)); i++)
	{
		PCMOutp32(rPCMTXFIFO, *(uPcmRecBuffer++));		

		if(uPcmRecBuffer ==uPcmEndRecBuffer)
		break;	
	}			

	if(uPcmRecBuffer ==uPcmEndRecBuffer)
		uPcmPlayDone=1;
			
	INTC_Enable(oPcm.m_uNumInt);
}


⌨️ 快捷键说明

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