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

📄 pcm.c

📁 samsung 最新芯片2450 的测试程序.
💻 C
📖 第 1 页 / 共 5 页
字号:
	I2SCODEC_WrSerial(0x34, 0x2d, 0x80); 	//Power Management(3) <<Power up L/ROUT1 outputs >>
	
		IIC_close();
	return 1;
	
	#endif
}

bool PCM_CodecInitPCMInOut(unsigned int eSync, unsigned char eMSBPos, unsigned int eSclk, unsigned char eClkSrc)
{
//play & record
	IIC_open( (unsigned int)200000);	//	Serial EEPROM IIC clk = 200KHz
	
	//					   address<<1 | data>>8,  data[7:0]
	I2SCODEC_WrSerial(0x34, 0x3e, 0x00);	//Reset

	I2SCODEC_WrSerial(0x34, 0x28, 0xd0);	//PWR Management(1) << Power up VMID[50Kohm]; VREF; VDAC >>
	I2SCODEC_WrSerial(0x34, 0x2e, 0x03);	//PWR Management(4) << Power up L/RMIX >>
	Delay(1000);
	
	I2SCODEC_WrSerial(0x34, 0x02, 0x08);	//DAC Control Mute
	I2SCODEC_WrSerial(0x34, 0x04, 0x00);	//ADC Control
	
	if (eSync == DURING_PCMSYNC_HIGH)
		I2SCODEC_WrSerial(0x34, 0x07, 0xb3);	//PCM Audio I/F Mode B
	else 
		I2SCODEC_WrSerial(0x34, 0x07, 0xa3);	//PCM Audio I/F Mode A
	I2SCODEC_WrSerial(0x34, 0x08, 0x0a);	//HiFi Audio I/F
	
	I2SCODEC_WrSerial(0x34, 0x0a, 0x33);	//Interface Control << Voice Codec >>
	
	if (eSync == SYNC_8K)
		I2SCODEC_WrSerial(0x34, 0x0c, 0x0c);	//Sync Rate Control 8KHz 
	else if (eSync == SYNC_16K)     
		I2SCODEC_WrSerial(0x34, 0x0c, 0x14);	//Sync Rate Control 16KHz 
	else if (eSync == SYNC_32K)
		I2SCODEC_WrSerial(0x34, 0x0c, 0x18);	//Sync Rate Control 32KHz
	else if (eSync == SYNC_48K)
		I2SCODEC_WrSerial(0x34, 0x0c, 0x00);	//Sync Rate Control 48KHz
	else if (eSync == SYNC_96K)	
		I2SCODEC_WrSerial(0x34, 0x0c, 0x1e);	//Sync Rate Control 96KHz
		
	I2SCODEC_WrSerial(0x34, 0x0e, 0x97); 	//Sample Rate Control (2), Don't care in case of slave mode
	I2SCODEC_WrSerial(0x34, 0x10, 0xff); 	//Left DAC Volume
	I2SCODEC_WrSerial(0x34, 0x12, 0xff); 	//Right DAC Volume
	I2SCODEC_WrSerial(0x34, 0x14, 0x0f); 	//Bass Control
	I2SCODEC_WrSerial(0x34, 0x16, 0x0f); 	//Treble Control
	I2SCODEC_WrSerial(0x34, 0x18, 0x7b); 	//ALC 1
	I2SCODEC_WrSerial(0x34, 0x1a, 0x00); 	//ALC 2
	I2SCODEC_WrSerial(0x34, 0x1c, 0x32); 	//ALC 3
	I2SCODEC_WrSerial(0x34, 0x1e, 0x00); 	//Noise Gate 
	I2SCODEC_WrSerial(0x34, 0x21, 0xc3); 	//Left ADC Volume
	I2SCODEC_WrSerial(0x34, 0x23, 0xc3); 	//Right ADC Volume
	I2SCODEC_WrSerial(0x34, 0x24, 0xc0); 	//Additional Control
	I2SCODEC_WrSerial(0x34, 0x26, 0x00); 	//Three D Control

	I2SCODEC_WrSerial(0x34, 0x28, 0xc0); 	//Power Management(1) << Power up VMID[50K ohm]; VREF >>
	I2SCODEC_WrSerial(0x34, 0x2a, 0x0c); 	//Power Management(2) << Power up ADCL/R >>
	I2SCODEC_WrSerial(0x34, 0x2c, 0x00); 	//Power Management(3)
	I2SCODEC_WrSerial(0x34, 0x2e, 0x00); 	//Power Management(4)

	I2SCODEC_WrSerial(0x34, 0x30, 0x00); 	//ID Register
	I2SCODEC_WrSerial(0x34, 0x32, 0x00); 	//Int. Polarty
	I2SCODEC_WrSerial(0x34, 0x34, 0x00);	//Int. Enable
	I2SCODEC_WrSerial(0x34, 0x36, 0x00);	//GPIO Control (1)
	I2SCODEC_WrSerial(0x34, 0x38, 0x00);	//GPIO Control (2)
	I2SCODEC_WrSerial(0x34, 0x40, 0x55);	//Record Mix (1)
	I2SCODEC_WrSerial(0x34, 0x42, 0x05);	//Record Mix (2)
	I2SCODEC_WrSerial(0x34, 0x44, 0x50);	//Left Out Mix(1)
	I2SCODEC_WrSerial(0x34, 0x47, 0x55);	//Left Out Mix(2) << Set the VXD2LO bit (Voice DAC to Left Output >>
	I2SCODEC_WrSerial(0x34, 0x48, 0x50);	//Rigth Out Mix(1)
	I2SCODEC_WrSerial(0x34, 0x4b, 0x55);	//Right Out Mix(2) << Set the VXD2RO bit (Voice DAC to Right Output) >>
	I2SCODEC_WrSerial(0x34, 0x4c, 0x50);	//Mono Out Mix(1)
	I2SCODEC_WrSerial(0x34, 0x4e, 0x55);	//Mono Out Mix(2)
	
	I2SCODEC_WrSerial(0x34, 0x51, 0x79);	//LOUT1 Volume << Set Left OUtput 1 Volume Update bit to '1' & Volume Level to Default >>
	I2SCODEC_WrSerial(0x34, 0x53, 0x79);	//ROUT1 Volume << Set Right OUtput 1 Volume Update bit to '1' & Volume Level to Default >>
	I2SCODEC_WrSerial(0x34, 0x54, 0x79);	//LOUT2 Volume
	I2SCODEC_WrSerial(0x34, 0x56, 0x79);	//ROUT2 Volume
	I2SCODEC_WrSerial(0x34, 0x58, 0x79);	//MONO Out
	I2SCODEC_WrSerial(0x34, 0x5a, 0x00);	//Output Control
	I2SCODEC_WrSerial(0x34, 0x5c, 0x05);	//ADC Input Mode << Set L/R ADC input select to Line 1/2 '01' >>
	
	I2SCODEC_WrSerial(0x34, 0x5e, 0x00);	//Input Control (1)
	I2SCODEC_WrSerial(0x34, 0x60, 0x00);	//Input Control (2)
	I2SCODEC_WrSerial(0x34, 0x62, 0x97);	//Left Input Volume
	I2SCODEC_WrSerial(0x34, 0x64, 0x97);	//Right Input Volume
	I2SCODEC_WrSerial(0x34, 0x66, 0x00);	//MIC Bias Comp Control
	
	I2SCODEC_WrSerial(0x34, 0x68, 0x04);	//Clock Control << Clock for Voice Codec = MCLK or PLL1
	I2SCODEC_WrSerial(0x34, 0x6a, 0x00);	//PLL1 Control (1)
	I2SCODEC_WrSerial(0x34, 0x6c, 0x83);	//PLL1 Control (2)
	I2SCODEC_WrSerial(0x34, 0x6e, 0x24);	//PLL1 Control (3)
	I2SCODEC_WrSerial(0x34, 0x71, 0xba);	//PLL1 Control (4)
	
	I2SCODEC_WrSerial(0x34, 0x72, 0x00);	//PLL2 Control (1)
	I2SCODEC_WrSerial(0x34, 0x74, 0x83);	//PLL2 Control (2)
	I2SCODEC_WrSerial(0x34, 0x76, 0x24);	//PLL2 Control (3)
	I2SCODEC_WrSerial(0x34, 0x79, 0xba);	//PLL2 Control (4)
	
	I2SCODEC_WrSerial(0x34, 0x7a, 0x00);	//Bias Control
	I2SCODEC_WrSerial(0x34, 0x7e, 0x00);	//Additional Control
	I2SCODEC_WrSerial(0x34, 0x2d, 0x80); 	//Power Management(3) <<Power up L/ROUT1 outputs >>
	
		IIC_close();
}


void PCM_CodecExitPCMOut(void)
{
	#if ( PCM_CODEC_NAME == AK2430)
	
		I2SCODEC_WrSerial(0x9e, 0x04, 0x01);	//EPL/R Amp Off		
		Delay(1300);

		I2SCODEC_WrSerial(0x9e, 0x07, 0x00);	//sw_COL Close and other sw Open
	   	I2SCODEC_WrSerial(0x9e, 0x08, 0x00);	//sw_COR Close and othr sw Open
	   	I2SCODEC_WrSerial(0x9e, 0x09, 0x00);	//sw_EPL, sw_EPR Amp output

		I2SCODEC_WrSerial(0x9e, 0x04, 0x00);	//RXSUM Off	
		I2SCODEC_WrSerial(0x9e, 0x05, 0x00);	//PCM Codec Off
	

	#elif ( PCM_CODEC_NAME == WM9713)
	
		AC97_Codec_Cmd(0,0x3E, 0xffff);		//Disable HPL/R output PGA's
		AC97_Codec_Cmd(0,0x26, 0xff00);		//Disable I/P PGA's nad Mixers
	
		Delay(1300);//added for continuous test
	#endif
	
}


void PCM_pcmtest1()
{
	int irqstatold, irqstatnew;
	
	printf("start tx dma disable test \n");
	
	rPCM_CTL1&= ~PCM_PCM_ENABLE;
	rPCM_CTL1&= ~PCM_TX_DMA_EN;
	
	irqstatold=rPCM_IRQ_STAT1;
	
	do
	{
		printf("tx fifo read for t32 test %x\n", rPCM_TXFIFO1);
		
		irqstatnew=rPCM_IRQ_STAT1;
		if(irqstatnew!=irqstatold)
		{
			printf("IRQ STAT : 0x%x, FIFO STAT : 0x%x\n", irqstatnew, rPCM_FIFO_STAT1);			
		}
		irqstatold = irqstatnew;
		
	}while (irqstatnew != 0xc80);
	
}

void PCM_pcmtest2()
{
	int irqstatold, irqstatnew;
	
	printf("start tx dma disable test \n");
	
	rPCM_CTL1&= ~PCM_PCM_ENABLE;
	rPCM_CTL1&= ~PCM_TX_DMA_EN;
	
	irqstatold=rPCM_FIFO_STAT1;
	
	do
	{
		printf("tx fifo read for t32 test %x\n", rPCM_TXFIFO1);
		
		irqstatnew=rPCM_FIFO_STAT1	;
		if(irqstatnew!=irqstatold)
		{
			printf("IRQ STAT : 0x%x, FIFO STAT : 0x%x fifo cnt : %d\n", rPCM_IRQ_STAT1, irqstatnew, irqstatnew>>14);
		}
		irqstatold = irqstatnew;		
	}while (irqstatnew != 0x3000);	
}

void PCM_fifostat()
{
	int fifostat=(g_oPCMState.PCMPort==0)?rPCM_FIFO_STAT0:rPCM_FIFO_STAT1;
	int irqstat=(g_oPCMState.PCMPort==0)?rPCM_IRQ_STAT0:rPCM_IRQ_STAT1;
	int	irqctrl=(g_oPCMState.PCMPort==0)?rPCM_IRQ_CTL0:rPCM_IRQ_CTL1;
	printf("FIFO STAT : 0x%x tx_fifo_cnt : %d rx_fifo_cnt : %d %s%s%s%s %s%s%s%s \n", fifostat, fifostat>>14, (fifostat>>4)&0x3f,
								(fifostat & FIFO_TXFIFO_EMPTY  			)?"TX empty  ":"",
								(fifostat & FIFO_TXFIFO_ALMOST_EMPTY	)?"TX almost empty  ":"",
								(fifostat & FIFO_TXFIFO_FULL   			)?"TX full  ":"",
								(fifostat & FIFO_TXFIFO_ALMOST_FULL 	)?"TX almost full  ":"",
								
								(fifostat & FIFO_RXFIFO_EMPTY  			)?"RX empty  ":"",
								(fifostat & FIFO_RXFIFO_ALMOST_EMPTY	)?"RX almost empty  ":"",
								(fifostat & FIFO_RXFIFO_FULL   			)?"RX full  ":"",
								(fifostat & FIFO_RXFIFO_ALMOST_FULL 	)?"RX almost full  ":""								
								);
	printf("IRQ  STAT : 0x%x  %s%s %s%s%s%s%s%s %s%s%s%s%s%s\n", irqstat,
								(irqstat & IRQ_PENDING			)?"irq pending  ":"",
								(irqstat & TRANSFER_DONE 		)?"transfer done  ":"",
								
								(irqstat & TXFIFO_EMPTY  		)?"TX empty  ":"",
								(irqstat & TXFIFO_ALMOST_EMPTY	)?"TX almost empty  ":"",								
								(irqstat & TXFIFO_FULL   		)?"TX full  ":"",
								(irqstat & TXFIFO_ALMOST_FULL 	)?"TX almost full  ":"",
								(irqstat & TXFIFO_ERROR_STARVE 	)?"TX starve  ":"",
								(irqstat & TXFIFO_ERROR_OVERFLOW)?"TX overflow  ":"",
								
								(irqstat & RXFIFO_EMPTY  		)?"RX empty  ":"",
								(irqstat & RXFIFO_ALMOST_EMPTY	)?"RX almost empty  ":"",								
								(irqstat & RXFIFO_FULL   		)?"RX full  ":"",
								(irqstat & RXFIFO_ALMOST_FULL 	)?"RX almost full  ":"",
								(irqstat & RXFIFO_ERROR_STARVE 	)?"RX starve  ":"",
								(irqstat & RXFIFO_ERROR_OVERFLOW)?"RX overflow  ":""								
								 );
	printf("IRQ  CTRL : 0x%x %s%s %s%s%s%s%s%s %s%s%s%s%s%s\n", irqctrl,	
								(irqctrl & EN_IRQ_TO_ARM 		)?"en irq to arm  ":"",
								(irqctrl & TRANSFER_DONE 		)?"transfer done  ":"",
								
								(irqctrl & TXFIFO_EMPTY  		)?"TX empty  ":"",
								(irqctrl & TXFIFO_ALMOST_EMPTY	)?"TX almost empty  ":"",								
								(irqctrl & TXFIFO_FULL   		)?"TX full  ":"",
								(irqctrl & TXFIFO_ALMOST_FULL 	)?"TX almost full  ":"",
								(irqctrl & TXFIFO_ERROR_STARVE 	)?"TX starve  ":"",
								(irqctrl & TXFIFO_ERROR_OVERFLOW)?"TX overflow  ":"",
								
								(irqctrl & RXFIFO_EMPTY  		)?"RX empty  ":"",
								(irqctrl & RXFIFO_ALMOST_EMPTY	)?"RX almost empty  ":"",								
								(irqctrl & RXFIFO_FULL   		)?"RX full  ":"",
								(irqctrl & RXFIFO_ALMOST_FULL 	)?"RX almost full  ":"",
								(irqctrl & RXFIFO_ERROR_STARVE 	)?"RX starve  ":"",
								(irqctrl & RXFIFO_ERROR_OVERFLOW)?"RX overflow  ":""								
								 );
	
}


void PCM_PCMSetting()
{
	bool bret;
	unsigned int uSclkDiv, uSyncDiv, uSclkSel;
	unsigned int uTxMsbPos, uRxMsbPos;

 	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; 

   	printf("uSclkDiv: 0x%x\n", uSclkDiv);
   	printf("uSyncDiv: 0x%x\n", uSyncDiv);

	{	
	double cdclk;
	double sclk;
	double syncclk;		
		
	cdclk = (g_oPCMState.PCMClkSrc == PCM_PCLK) ? (double)PCLK : (double)g_oPCMState.EXTCDCLKFreq;
	sclk 	= cdclk/(2*(  uSclkDiv+ 1)  );	
	syncclk = sclk /(     uSyncDiv+ 1   );		
		
	printf("Actural value\n\
Source_Clk : %f	PCM_SCLK : %fKHz	PCM_Syncclk: %fKHz\n",
cdclk, sclk, syncclk);			
	}

	if(g_oPCMState.PCMMSBPosition == AFTER_PCMSYNC_HIGH)//min 17fs is needed for recording
	{
		uTxMsbPos = TX_MSB_POS1;
		uRxMsbPos = RX_MSB_POS1;	
	}
	else if(g_oPCMState.PCMMSBPosition == DURING_PCMSYNC_HIGH)//min 16fs is needed
	{
		uTxMsbPos = TX_MSB_POS0;
		uRxMsbPos = RX_MSB_POS0	;
	}

	//PCM Clock Setting & Transfer data setting
	if(g_oPCMState.PCMPort == PCM_PORT0)
	{
		rPCM_CLKCTL0 = ( uSclkSel | (uSclkDiv<<9) | (uSyncDiv<<0) );
		rPCM_CTL0 = ( uTxMsbPos |uRxMsbPos);//pcm_txfifo_disable
	}
	else
	{
		rPCM_CLKCTL1 = ( uSclkSel | (uSclkDiv<<9) | (uSyncDiv<<0) );
		rPCM_CTL1 = ( uTxMsbPos |uRxMsbPos);//pcm_txfifo_disable			
	}

}


void PCM_TXFIFOwaitTillFULL()
{
	if(g_oPCMState.PCMPort == PCM_PORT0)
	{
		while( FIFO_TXFIFO_COUNT0<16) ;
	}
	else
	{
		while( FIFO_TXFIFO_COUNT1<16) ;			
	}	
}

void PCM_TXFIFOwaitTillEmpty()
{
	if(g_oPCMState.PCMPort == PCM_PORT0)
	{
		while( FIFO_TXFIFO_COUNT0!=0) ;
	}
	else
	{
		while( FIFO_TXFIFO_COUNT1!=0) ;			
	}

}


void PCM_PCMInDMASetting(unsigned int uRecBufferAddr, unsigned int uPcmSize)
{
	unsigned char Burst, Datasize;
	unsigned char rBurst, rDatasize;
	unsigned int estInitialTC;//
	unsigned int realInitialTC;


	Burst = 1;//1: single, 4 : 4burst - doesn't work?	
	Datasize = 4;//1:byte, 2:half word 4:word [transfer unit]
	
	rBurst = (Burst == 1)? 0 : 1;//0:single, 1:4 burst
	rDatasize = (Datasize==1)?0:
				(Datasize==2)?1:2;//0:byte, 1:half word, 2: word.		
	estInitialTC = uPcmSize/ (  Burst*Datasize  );// playsize(byte) / (  single or burst * transfer unit ) = tc
		
	if(estInitialTC > 0xfffff )//2^20 = 1M
	{
		realInitialTC = 0xfffff;
		printf("size of data to record are larger than DMA count max, it adjusted from %d to %d\n\
or you can use dma autoreload function\n", estInitialTC, realInitialTC);
	}
	else
		realInitialTC = estInitialTC;
	
	//DMA Setting	
	rDISRC2  = (g_oPCMState.PCMPort == PCM_PORT0)? ((unsigned int)0x5c00000c) : ((unsigned int)0x5c00010c);//PCM Input Data FIFO
	rDISRCC2 = (1<<1) + (1<<0);          //APB, Fix  
	
	rDIDST2  = uRecBufferAddr;   //Record PCM buff loc
	rDIDSTC2 = (0<<1) + (0<<0);          //AHB, Increment
	// 31: demand 	30: sync pclk  29:curr_tc int setting 28:unit transfer 27:single service 22: auto reload off  20: half word 
	rDCON2   = (U32)(0<<31)+(0<<30)+(1<<29)+(rBurst<<28)+(0<<27)+(1<<22)+(rDatasize<<20)+realInitialTC;
	rDMAREQSEL2 = (g_oPCMState.PCMPort == PCM_PORT0)? ( (13<<1) + (1<<0) ) :  ( (15<<1) + (1<<0) );	
	
}



void PCM_PCMOutDMASetting(unsigned int uPlayBufferAddr, unsigned int uPcmSize)
{
	unsigned char Burst, Datasize;
	unsigned char rBurst, rDatasize;
	unsigned int estInitialTC;//
	unsigned int realInitialTC;


	Burst = 1;//1: single, 4 : 4burst - doesn't work?	
	Datasize = 4;//1:byte, 2:half word 4:word [transfer unit]
	
	rBurst = (Burst == 1)? 0 : 1;//0:single, 1:4 burst
	rDatasize = (Datasize==1)?0:
				(Datasize==2)?1:2;//0:byte, 1:half word, 2: word.		
	estInitialTC = uPcmSize/ (  Burst*Datasize  );// playsize(byte) / (  single or burst * transfer unit ) = tc
		
	if(estInitialTC > 0xfffff )//2^20 = 1M
	{
		realInitialTC = 0xfffff;
		printf("size of data to record are larger than DMA count max, it adjusted from %d to %d\n\
or you can use dma autoreload function\n", estInitialTC, realInitialTC);
	}
	else
		realInitialTC = estInitialTC;
		//DMA Setting
	rDISRC1  = uPlayBufferAddr;                 
	rDISRCC1 = (0<<1) + (0<<0);		//The source is in the system bus(AHB), Increment      
	rDIDST1  = (g_oPCMState.PCMPort == PCM_PORT0)? ((unsigned int)0x5c000008) : ((unsigned int)0x5c000108);//PCM Out Data Fifo    
	rDIDSTC1 = (0<<2)+ (1<<1) + (1<<0);     //int will occur when tc reaches 0, The destination is in the peripheral bus(APB), Fixed  
	// 31: demand	30: sync pclk  29:curr_tc 0 intterupt on 28:unit transfer 27:single service 22: auto reload off  20: half word 
	rDCON1   = (U32)(0<<31)+(0<<30)+(1<<29)+(rBurst<<28)+(0<<27)+(1<<22)+(rDatasize<<20)+realInitialTC;//[28] 0 unit, [20] 2'b10 word. [19:0]count
	rDMAREQSEL1 = (g_oPCMState.PCMPort == PCM_PORT0)? ( (12<<1) + (1<<0) ) :  ( (14<<1) + (1<<0) );
}

//pcmsize(byte) 16bit mono continous format
bool PCM_PCMInDMA(unsigned int uRecBufferAddr, 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;

	//IRQ Initialization
	g_interrupt_cnt=0;
	if(g_oPCMState.PCMPort == PCM_PORT0)

⌨️ 快捷键说明

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