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

📄 iis.c

📁 samsung 最新芯片2450 的测试程序.
💻 C
📖 第 1 页 / 共 5 页
字号:
	PCM_Data_init(IIS_BUFFER, g_oI2SState.pcmsize);
	I2S_record_main( (void *)IIS_BUFFER, g_oI2SState.pcmsize, g_oI2SState.LineMic);
	
//play	
	if(g_oI2SState.benUnderInt==1)I2S_INT_Underrun_init();	
	I2S_play_main( (void *)IIS_BUFFER, g_oI2SState.pcmsize);
	
//deinit	
	I2S_DisableInt();
	IIS_Port_Return();
}

//Record Sound via Line-In 
void RecordSound_ViaLineIn_Playit_logic(void)
{	
//setting
	g_oI2SState.BitperCh = 24;
	g_oI2SState.SyncClkFreq = 96000;
	g_oI2SState.Totch =2;//(fixed)
	
	g_oI2SState.CDCLKFreqFs = 384;
	g_oI2SState.CDCLKFreq = g_oI2SState.CDCLKFreqFs * g_oI2SState.SyncClkFreq;
	g_oI2SState.BitClkFS = 48;
	Select_EPLL(g_oI2SState.Port, 0);
	
	g_oI2SState.DmaPolling = I2S_POLLING;	
	g_oI2SState.recordSec=10;
	g_oI2SState.pcmsize = g_oI2SState.SyncClkFreq*g_oI2SState.Totch*g_oI2SState.BitperCh/8*g_oI2SState.recordSec;

	g_oI2SState.ben24bittest=1;//stop at playing at the half.
	
//init	
	IIS_Port_Init();
	
//record 
	PCM_Data_init(IIS_BUFFER, g_oI2SState.pcmsize);
	
	if(!I2S_InitCodec( g_oI2SState.CodecID, g_oI2SState.MasterSlave,I2S_MODE_RX, g_oI2SState.Dataformat,g_oI2SState.CDCLKFreqFs, g_oI2SState.SyncClkFreq, g_oI2SState.BitperCh,CODEC_LINEIN) )return;//2450 -OpMode, txr, dataformat, CodecClkFs(slave), BitperCh
	I2S_Setting(g_oI2SState.Port, g_oI2SState.MasterSlave, I2S_MODE_RX, g_oI2SState.Dataformat,g_oI2SState.CDCLKFreqFs, g_oI2SState.BitClkFS, g_oI2SState.Totch, g_oI2SState.BitperCh, g_oI2SState.DmaPolling);//Port, trx, i2sformat, rootfs, ch, bit);
	IIS_RecSound_Polling_logic(RECORD_LINE_IN, IIS_BUFFER, g_oI2SState.pcmsize);
	
//play	
	if(g_oI2SState.benUnderInt==1)I2S_INT_Underrun_init();	
	I2S_play_main( (void *)IIS_BUFFER, g_oI2SState.pcmsize);
	
//deinit	
	I2S_DisableInt();
	IIS_Port_Return();
}


void RECORD_PLAY_SIMtaneously(void)
{
	printf("\nRecord and Play Simultaneously.\n");

//init
	IIS_Port_Init(); 	

//play record pcm & record
	PCM_Data_init(IIS_BUFFER2, g_oI2SState.pcmsize);
	I2S_playrecord_main((void *)IIS_BUFFER, g_oI2SState.pcmsize, (void *)IIS_BUFFER2, g_oI2SState.pcmsize, g_oI2SState.LineMic);
	
//play	record pcm
	if(g_oI2SState.benUnderInt==1)I2S_INT_Underrun_init();	
	I2S_play_main( (void *)IIS_BUFFER2, g_oI2SState.pcmsize);
	I2S_DisableInt();
	
	IIS_Port_Return();
}



// before prior version, byte was written into tc.
//  if correct that, it would work. but this version would be more clear
//dma infor, array init.
//ch : channel 0 for tx, 1 for rx for general
void I2S_DMA_arrayinit(unsigned char ch)
{
	int i=0;
		
	g_oDmainfo[ch].uIndex=0;
	g_oDmainfo[ch].uNums=0;
	
	while(g_oDmainfo[ch].uUnitsizeByte*(i+1) < g_oDmainfo[ch].uTotalsizeByte)
	{
		g_oDmainfo[ch].oArray[i].uStartAddr = 
			g_oDmainfo[ch].uStartAddr + g_oDmainfo[ch].uUnitsizeByte*i;
			
		g_oDmainfo[ch].oArray[i].uSizeByte = g_oDmainfo[ch].uUnitsizeByte;
		
		g_oDmainfo[ch].oArray[i].uTC	   = 
			g_oDmainfo[ch].oArray[i].uSizeByte / g_oDmainfo[ch].uBytePerTC;		
			
		i++;
		g_oDmainfo[ch].uNums++;
		
		if(g_oDmainfo[ch].uNums >= MAX_I2S_DMA_array-1 ) break;
	}

	g_oDmainfo[ch].oArray[i].uStartAddr = 
		g_oDmainfo[ch].uStartAddr + g_oDmainfo[ch].uUnitsizeByte*i;
		
	g_oDmainfo[ch].oArray[i].uSizeByte = 
		g_oDmainfo[ch].uTotalsizeByte%g_oDmainfo[ch].uUnitsizeByte;
	
	g_oDmainfo[ch].oArray[i].uTC	   = 
		g_oDmainfo[ch].oArray[i].uSizeByte / g_oDmainfo[ch].uBytePerTC;		
		
	i++;
	g_oDmainfo[ch].uNums++;
	
	//printinfo.
	printf("total size %d byte(0x%x), unit size %d byte(0x%x)  num of unit %d\n",
			 g_oDmainfo[ch].uTotalsizeByte, g_oDmainfo[ch].uTotalsizeByte,
			 g_oDmainfo[ch].uUnitsizeByte, g_oDmainfo[ch].uUnitsizeByte, g_oDmainfo[ch].uNums);
	
	for(i=0; i<g_oDmainfo[ch].uNums; i++)
	{
		printf("%d . addr:%x  size:%d byte(0x%x)  tc:%d unit(0x%x)\n",
		 i, g_oDmainfo[ch].oArray[i].uStartAddr, g_oDmainfo[ch].oArray[i].uSizeByte, g_oDmainfo[ch].oArray[i].uSizeByte,
		 g_oDmainfo[ch].oArray[i].uTC, g_oDmainfo[0].oArray[i].uTC);
	}
	
}

//address, tc update
//return : true : finised , false : not finished.
bool I2S_DMA_updateTx()
{	
	bool bret;
	if(g_oDmainfo[0].uIndex<g_oDmainfo[0].uNums)
	{
		printf("at %d th\n", g_oDmainfo[0].uIndex);
		
		rDISRC2  = g_oDmainfo[0].oArray[g_oDmainfo[0].uIndex].uStartAddr;	
		rDCON2 = rDCON2 & ~(0xfffff) | g_oDmainfo[0].oArray[g_oDmainfo[0].uIndex].uTC;
		bret=0;
	}
	else if(g_oDmainfo[0].uIndex==g_oDmainfo[0].uNums)//before finish	
	{
		printf("before finish\n");
			
		rDCON2 = rDCON2 & ~(1<<22) | (1<<22);//autoreload off;
		rDIDSTC2 = rDIDSTC2 & ~(1<<2) | (0<<2);//interrupt occur at tc reach zero
		
		//printf("will be repeated next\n");
		//g_oDmainfo[0].uIndex=0;
		//I2S_DMA_updateTx();		
		bret=0;
	}
	else if(g_oDmainfo[0].uIndex > g_oDmainfo[0].uNums)//at finish
	{
		//dma done.
		Play_Done = 1;
		printf("at finish\n");
		bret=1;
	}

	g_oDmainfo[0].uIndex++;
	return bret;
	
}


bool I2S_DMA_updateRx()
{	
	bool bret;
	if(g_oDmainfo[1].uIndex<g_oDmainfo[1].uNums)
	{
		printf("at %d th\n", g_oDmainfo[1].uIndex);		
		
		rDIDST1  = g_oDmainfo[1].oArray[g_oDmainfo[1].uIndex].uStartAddr;	
		rDCON1 = rDCON1 & ~(0xfffff) | g_oDmainfo[1].oArray[g_oDmainfo[1].uIndex].uTC;
		bret=0;
	}
	else if(g_oDmainfo[1].uIndex==g_oDmainfo[1].uNums)//before finish	
	{
		printf("before finish\n");
			
		rDCON1 = rDCON1 & ~(1<<22) | (1<<22);//autoreload off;
		rDIDST1 = rDIDST1 & ~(1<<2) | (0<<2);//interrupt occur at tc reach zero
		
		//printf("will be repeated next\n");
		//g_oDmainfo[1].uIndex=0;
		//I2S_DMA_updateRx();		
		bret=0;
	}
	else if(g_oDmainfo[1].uIndex > g_oDmainfo[1].uNums)//at finish
	{
		//dma done.
		Rec_Done = 1;
		printf("at finish\n");
		bret=1;
	}

	g_oDmainfo[1].uIndex++;
	return bret;
	
}

void I2S_DMA_Play_init(int port, unsigned char *start_addr, unsigned int pcm_size, int bitperch)
{
	unsigned char Exit_Key;

	unsigned char Burst, Datasize;
	unsigned char rBurst, rDatasize;
	unsigned int estInitialTC;//
	unsigned int realInitialTC;

//dma init
	//size estimate,
	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 = pcm_size/ (  Burst*Datasize  );// playsize(byte) / (  single or burst * transfer unit ) = tc
		
		
	pISR_DMA = (unsigned)DMA2_Done;
	ClearPending(BIT_DMA);
	rSUBSRCPND = BIT_SUB_DMA2;

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

	printf("\nConnect head-phone plug into speaker-out socket on SMDK2450 and Press any key.\n");
	getchar();
	
	printf("If you want to exit, Press the 'x' key.\n");
	printf("Now Play...\n");
	
	printf("If you want to disable IIS tx(PAUSE), Press '0' key\n");
	printf("If you want to enable IIS tx, Press '1' key\n");
	printf("If you want to stop DMA channel(STOP), Press '2' key\n");
	printf("If you want to start DMA channel, Press '3' key\n");
	printf("If you want to test underrun interrupt, Press 'u' key\n");

	
	//DMA2 Register Setting 
	//rDISRC2  = (int)(start_addr);	
	rDISRCC2 = (0<<1) + (0<<0); 
	
	if(port == I2S_PORT0) rDIDST2  = ((unsigned int)0x55000010);
	else rDIDST2  = ((unsigned int)0x55000110);
	rDIDSTC2 = (1<<2)+(1<<1) + (1<<0);//interrup at after autoreload, apb,fixed
	
	// 31: ACK 	30: sync pclk  29:curr_tc int setting 28:unit transfer 27:single service 22: 0-auto reload on  20: word 
	rDCON2   = (U32)((1<<31)+(0<<30)+(1<<29)+(rBurst<<28)+(0<<27)+(0<<22)+(rDatasize<<20) );//+realInitialTC );		
	
	// 5:1= 4th bit is the tx iis     0:set = hw zero = sw
	rDMAREQSEL2 = (port == I2S_PORT0)? (4<<1)|(1) : (6<<1)|(1);//port0 / 1	
	
	
	g_oDmainfo[0].uStartAddr = (unsigned int )start_addr;
	g_oDmainfo[0].uTotalsizeByte = (unsigned int)pcm_size;
	//g_oI2Splaybuffer.unitsizeByte = 0xfffff*Burst*Datasize;//byte	(due to make 4*6 unit)
	g_oDmainfo[0].uUnitsizeTC	 = 0x80000;
	g_oDmainfo[0].uUnitsizeByte = 0x80000*Burst*Datasize;//byte	(due to make 4*6 unit)
	g_oDmainfo[0].uBytePerTC	 = Burst*Datasize;
	
	I2S_DMA_arrayinit(0);
	
}

void I2S_tx_start()
{
	if(g_oI2SState.Port == I2S_PORT0)
	{
		while( (rIISCON & 0x100)==0x000 ) ;//wait during tx0 not full 
		
		//even 4ch, 6ch checking one pairs is enough		
		//ok - fifo are full
		
		rIISCON |= 0x1;		 //IIS Interface start
	}
	else
	{
		while( (rIISCON1 & 0x100)==0x000 ) ;//wait during not full	
	
		rIISCON1 |= 0x1;	 //IIS Interface start
	}
}


void I2S_tx_finish()
{
	int i;
	if(g_oI2SState.Port == I2S_PORT0)
	{
		while( (rIISCON & 0x400)==0x000 ) 
		{
			i++;//wait during tx0 not empty
			if(i>0x2000000) {
				printf("tx fifo time out \n");
				break;	
			}
				
		}
		//even 4ch, 6ch checking one pairs is enough	
		rIISCON	 &= ~(1<<0);	    //IIS Interface stop
	}
	else
	{
		while( (rIISCON1 & 0x400)==0x000 ) 
		{
			i++;//wait during tx not empty
			if(i>0x2000000) {
				printf("tx fifo time out \n");
				break;	
			}
		}
		rIISCON1	 &= ~(1<<0);	    //IIS Interface stop
		
		
	}	
	printf("playing is finished\n");	
}

void I2S_DMA_finishTX()
{
	rDMASKTRIG2  = (1<<2);	 //DMA2 stop
	rINTSUBMSK |= (BIT_SUB_DMA2);
	rINTMSK |= (BIT_DMA);	
}

//play_size = byte
void IIS_PlayWave_DMA(int port , unsigned char *start_addr)
{
	unsigned char Exit_Key;

//dma init, array init.
	//already done
	
	Play_Done=0;
	g_underruncnt=0;
	I2S_DMA_updateTx();
	
//dma start	
	rDMASKTRIG2 = (0<<2) + (1<<1) + (0<<0);	    //No-stop, DMA2 channel On, and No-sw trigger        
    
    I2S_DMA_updateTx();
           
	//IIS Tx Start
	I2S_tx_start();
	
	rGPHDAT = 0x755f;
	

	while(!Play_Done)
	{
		#if 1
		Exit_Key=Uart_GetKey();

		
    	if(Exit_Key == '0'){
    		if(port == I2S_PORT0) 	rIISCON |= (1<<4);//tx pause
    		else 					rIISCON1 |= (1<<4);
    		printf("\nPAUSE...\n");
    	}
		if(Exit_Key == '1'){
			//rIISCON &= ~(1<<3);//strange
			if(port == I2S_PORT0) 	rIISCON &= ~(1<<4);//tx no pause
			else					rIISCON1 &= ~(1<<4);
		}
		if(Exit_Key == '2'){//dma pause
			//rDMASKTRIG2 |= (1<<2);
			if(port == I2S_PORT0) 	
			{
				//rIISFIC &= ~(1<<13);	//* tx fifo disable
				//while( (rIISCON & 0x800)==0x000 ) ;//wait during left	
				//rIISCON0 |= (1<<6);	// dma pause				
				//pause after sending right.
				//while( (rIISFIC & 0x1F00)!=0x0000 );	//* wait until tx fifo gets empty	
				rIISCON |= (1<<6);	// dma pause	
			}
			else
			{			
				rIISCON1 |= (1<<6);	// dma pause	
			}
    			printf("\nSTOP...\n");
		}
		if(Exit_Key == '3'){
			//rIISFIC |= (1<<13);	//* tx fifo enable			
			//while( (rIISCON & 0x800)==0x000 ) ;//wait during left
			
			if(port == I2S_PORT0) 		rIISCON &= ~(1<<6);	//dma no pause
			else  					rIISCON1 &= ~(1<<6);//dma no pause
			//rDISRC2  = (int)(start_addr);			
			//rDMASKTRIG2 &= ~(1<<2);
			//rDMASKTRIG2 |= (1<<1);
		}


		if(Exit_Key == '4'){//dma pause
			rDMASKTRIG2  = (1<<2);	 //DMA2 stop
    			printf("\ndma STOP...\n");
		}
		if(Exit_Key == '5'){//dma continue
			rDMASKTRIG2 &= ~(1<<2);
			rDMASKTRIG2 |= (1<<1);
		}		
		
		if(Exit_Key == 'u'){//fifo flush
			if(port == I2S_PORT0) 	
			{
				rIISFIC = 0+(1<<15);
			    rIISFIC = 0+(0<<15);				
			}
			else
			{
				rIISFIC1 = 0+(1<<15);
			    rIISFIC1 = 0+(0<<15);								
			}
		}
		

		if( (Exit_Key == 'x') | (Exit_Key == 'X')) 
			break;
		#endif
		;

		
		//printf("STAT2: 0x%x CURR_TC: 0x%x		DCDST2: 0x%x\n", rDSTAT2&0x300000, rDSTAT2&0xfffff, rDCDST2);		
		
	}

	//IIS Tx Stop
	//Delay(10);			 //For end of H/W Tx
//	I2S_tx_finish();	//already done at dma end

⌨️ 快捷键说明

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