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

📄 iis.c

📁 三星2443芯片
💻 C
📖 第 1 页 / 共 3 页
字号:
/*======================================================================

 Project Name : S3C2443

 Copyright 2006 by Samsung Electronics, Inc.
 All rights reserved.

 Project Description :
 This software is only for verifying functions of the S3C2443. 
 Anybody can use this code without our permission.

 File Name    : iis.c
 Description  : S3C2443 IIS module code
 Author       : Junon Jeon
 Dept         : AP
 Created Date : 2006.06.02
 Version      : 0.0
 History
   R0.0 (2006.06.02): Junon draft
		- S3C2443 IIS test code is derived from S3C2413A IIS test code.
		
=======================================================================*/

#include "System.h"
#include "iis.h"	



#define IIS_BUFFER 0x31000000

#define REC_LEN_IIS 0xfffff*4	//Max value of DMA Transfer Counter (20bit) = 0xfffff, Date Size=Word (4bytes)
#define PLAY_IIS    0
#define RECORD_MIC_IN  1
#define RECORD_LINE_IN 2 
#define RECORD_PLAY_SIM 3
 
#define L3C (1<<2)	// GPG2 = L3CLOCK
#define L3D (1<<1)	// GPG1 = L3DATA 
#define L3M (1<<0)	// GPG0 = L3MODE

// Global variables
char which_Buf = 1;
volatile char Rec_Done = 0;

unsigned char  *Buf,*_temp;
unsigned char *rec_buf = (unsigned char *)(IIS_BUFFER+0x28);
unsigned char *rec_buf1 = (unsigned char *)(IIS_BUFFER + REC_LEN_IIS); 

unsigned int size, fs; 
unsigned int save_GPE_CON, save_GPG_CON;
unsigned int save_GPE_DAT, save_GPG_DAT;

float IIS_Codec_CLK;

// Functions
// GPIO port setting
void IIS_Port_Init(void);
void IIS_Port_Return(void);
// L3 inteface function for initializing UDM1341
void _WrL3Addr(unsigned char data);
void _WrL3Data(unsigned char data,int halt);
void Init1341(int);
// IIS library
unsigned int IIS_Select_SamplingRate(void);
void Select_IIS_Master_CLK(void);
void Select_PCLK(void);
void Select_EXTCLK(void);
void Select_EPLL(void);
void Select_EPLL_Ref_CLK(void);
void down_wav(void);

void __irq Rx_IIS_Int(void);
void __irq DMA1_Rec_Done(void);
void __irq DMA2_Done(void);
void __irq Play_Rec_Simul(void);


void Play_Iis(void);
void IIS_RecSound_DMA1( int mode, unsigned int rec_size);
void IIS_RecSound_DMA1_Repeat(unsigned char *start_addr, unsigned int rec_size);
void IIS_PlayWave_DMA2(unsigned char *start_addr, unsigned int play_size);
void IIS_Paly_Rec_Simul(unsigned char *start_addr, unsigned int play_size);
void IIS_RecSound_DMA1_SLV(int mode, unsigned int rec_size);
void RecordSound_ViaLineIn_SLV(void);
void Play_Iis_MASTER(void);
void Data_init(void);
void IIS_PlayWave_DMA2_MASTER(unsigned char *start_addr, unsigned int play_size);
void RecordSound_ViaLineIn_MASTER(void);
void IIS_RecSound_DMA1_MASTER(int mode, unsigned int rec_size);
void Play_Iis_SLAVE(void);
void IIS_PlayWave_DMA2_SLAVE(unsigned char *start_addr, unsigned int play_size);
void Play_Iis_EXTCLK(void);
void IIS_PlayWave_DMA2_EXTCLK(unsigned char *start_addr, unsigned int play_size);

void * func_iis_test[][2]=
{	
	//IIS Function Test Item
	//  									"123456789012345678901"
   	(void *)Play_Iis,              			       "Play Wave            ", 
   	(void *)RecordSound_ViaMICIn_Playit,           "Record(MicIn) & Play ",
   	(void *)RecordSound_ViaLineIn_Playit, 	       "Record(LineIn) & Play",
    (void *)RECORD_PLAY_SIMtaneously,              "Record and Play Simultaneously. ", 
    (void *)RecordSound_ViaLineIn_MASTER,          "RECORD MASTER MODE",
    (void *)Play_Iis_MASTER,              		   "PLAY  MASTER MODE           ",     
    (void *)RecordSound_ViaLineIn_SLV,             "RECORD SLAVE MODE",
    (void *)Play_Iis_SLAVE,              		   "PLAY  SLAVE MODE           ",         
    (void *)Play_Iis_EXTCLK,                 "PLAY  EXT CDCLK            ",
    0,0
};


void Test_IIS(void)
{
	int i;
		
	while(1)
	{
		i=0;
		printf("\n\n================== IIS Function Test =====================\n\n");
		
		while(1)
		{   //display menu
			printf("%2d:%s",i,func_iis_test[i][1]);
			i++;
			if((int)(func_iis_test[i][0])==0)
			{
				printf("\n");
				break;
			}
			if((i%1)==0)
			printf("\n");
		}
		printf("\n==========================================================\n");
		printf("Select #Item or Press Enter key to exit : ");
		i = GetIntNum(); 
		if(i==-1) break;		// return.
		if(i>=0 && (i<((sizeof(func_iis_test)-1)/8)) )	// select and execute...
			( (void (*)(void)) (func_iis_test[i][0]) )();
	}
	
}


//============================== [ IIS Drivers ] ===============================

// Setting Port related to IIS  
void IIS_Port_Init(void)
{
	save_GPG_CON = rGPGCON;	// L3
	save_GPE_CON = rGPECON;	// IIS
   	
   	//----------------------------------------------------------
	//PORT G GROUP
	//Ports  :   GPG0       GPG1        GPG2  
	//Signal :  L3MODE     L3DATA      L3CLK
	//Setting:  OUTPUT     OUTPUT      OUTPUT 
	//	        [1:0]      [3:2]       [5:4]
	//Binary :  01          01           01 
	//----------------------------------------------------------    
    rGPGCON = rGPGCON & ~(0x3f) | (1<<4)|(1<<2)|(1); // output setting
   
   	//-------------------------------------------------------------------------------
	//PORT E GROUP
	//Ports  :   GPE4  			GPE3           GPE2         GPE1           GPE0 
	//Signal :   I2S DO         I2S DI         CDCLK        I2S CLK        I2S LRCLK
	//Binary :   10,            10,            10,          10,            10  
	//-------------------------------------------------------------------------------
	rGPECON = rGPECON & ~(0x3ff) | 0x2aa; // IIS function setting
	rGPEUDP = 0xffffffff; // pull_up_down disable
}


void IIS_Port_Return(void)
{
	rGPGCON = save_GPG_CON;
   	rGPECON = save_GPE_CON;
}


// L3 interface library
void _WrL3Addr(unsigned char data)
{	 
 	int i,j;

   	rGPGDAT  = rGPGDAT & ~(L3D | L3M | L3C) | L3C;	//L3D=L, L3M=L(in address mode), L3C=H

   	for(j=0;j<4;j++);	 //tsu(L3) > 190ns

   	for(i=0;i<8;i++)	//LSB first
   	{
	  	if(data & 0x1)	//If data's LSB is 'H'
	  	{
			rGPGDAT &= ~L3C;	//L3C=L
			rGPGDAT |= L3D;		//L3D=H		 
			for(j=0;j<4;j++);	//tcy(L3) > 500ns
			rGPGDAT |= L3C;		//L3C=H
			rGPGDAT |= L3D;		//L3D=H
			for(j=0;j<4;j++);	//tcy(L3) > 500ns
	  	}
	  	else		//If data's LSB is 'L'
	  	{
			rGPGDAT &= ~L3C;	//L3C=L
			rGPGDAT &= ~L3D;	//L3D=L
			for(j=0;j<4;j++);	//tcy(L3) > 500ns
			rGPGDAT |= L3C;	    //L3C=H
			rGPGDAT &= ~L3D;	//L3D=L
			for(j=0;j<4;j++);	//tcy(L3) > 500ns		
	  	}
	  	data >>= 1;
   	}

   	rGPGDAT  = rGPGDAT & ~(L3D | L3M | L3C) | (L3C | L3M);	 //L3M=H,L3C=H   
}


void _WrL3Data(unsigned char data,int halt)
{
 	int i,j;

   	if(halt)
   	{
	  	rGPGDAT  = rGPGDAT & ~(L3D | L3M | L3C) | L3C;   //L3C=H(while tstp, L3 interface halt condition)	  
	  	for(j=0;j<4;j++);		//tstp(L3) > 190ns
   	}

   	rGPGDAT  = rGPGDAT & ~(L3D | L3M | L3C) | (L3C | L3M);   //L3M=H(in data transfer mode)	  
   	for(j=0;j<4;j++);		//tsu(L3)D > 190ns

   	for(i=0;i<8;i++)
   	{
	  	if(data & 0x1)	//if data's LSB is 'H'
	  	{
	    	rGPGDAT &= ~L3C;		//L3C=L
	    	rGPGDAT |= L3D;			//L3D=H
			for(j=0;j<4;j++);		//tcy(L3) > 500ns
	    	rGPGDAT |= (L3C | L3D);	//L3C=H,L3D=H
	    	for(j=0;j<4;j++);		//tcy(L3) > 500ns
	  	}
	  	else		//If data's LSB is 'L'
	  	{
	    	rGPGDAT &= ~L3C;		//L3C=L
	    	rGPGDAT &= ~L3D;		//L3D=L
	    	for(j=0;j<4;j++);		//tcy(L3) > 500ns
	    	rGPGDAT |= L3C;			//L3C=H
	    	rGPGDAT &= ~L3D;		//L3D=L
	    	for(j=0;j<4;j++);		//tcy(L3) > 500ns
	  	}
		data >>= 1;		//For check next bit
   	}

   	rGPGDAT  = rGPGDAT & ~(L3D | L3M | L3C) | (L3C | L3M);    //L3M=H,L3C=H
}


//Initialization of UDA1341 Audio Codec using L3 Interface 
void Init1341(int mode)
{
    rGPGDAT = rGPGDAT & ~(L3M|L3C|L3D) |(L3M|L3C);  //Start condition : L3M=H, L3C=H
 
 
	if(mode == PLAY_IIS)
    {	//L3 Interface
	    _WrL3Addr(0x14 + 2);     //STATUS (000101xx+10)
	 	_WrL3Data(0x50,0);	 //0,1,01, 000,0 : Status 0,Reset, 384fs,IIS-bus,no DC-filtering
//	 	_WrL3Data(0x60,0);	 //0,1,10, 000,0 : Status 0,Reset, 256fs,IIS-bus,no DC-filtering	 	
//	 	_WrL3Data(0x40,0);	 //0,1,00, 000,0 : Status 0,Reset, 512fs,IIS-bus,no DC-filtering	 	
		
		_WrL3Addr(0x14 + 2);     //STATUS (000101xx+10)
	    _WrL3Data(0x81,0);	 //bit[7:0] => 1,0,0,0, 0,0,01 
    }
	//Record Sound via MIC-In
    if(mode == RECORD_MIC_IN)
    {
	  	_WrL3Addr(0x14 + 2);    //STATUS (000101xx+10)
		_WrL3Data(0xa2,0);	//bit[7:0] => 1,0,1,0,0,0,10
		
		_WrL3Addr(0x14 + 0);    //DATA0 (000101xx+00)
       	_WrL3Data(0xc2, 0);	//1100 0,010  : Extended addr(3bits), 010 
        _WrL3Data(0xf2, 0);	//111,100,10 : DATA0, MIC Amplifier Gain 21dB, input channel 2 select (input channel 1 off)              
    }
	//Record Sound via Line-In
   	if(mode == RECORD_LINE_IN)
   	{
	  	_WrL3Addr(0x14 + 2);    //STATUS (000101xx+10)
		_WrL3Data(0xa2,0);	//bit[7:0] => 1,0,1,0, 0,0,10 Gain of ADC 6dB, ADC(on) DAC(off)
		
		_WrL3Addr(0x14 + 0);    //DATA0 (000101xx+00)
       	_WrL3Data(0xc2, 0);	//1100 0,010  : Extended addr(3bits), 010 
      	_WrL3Data(0xf1, 0);	//111,100,01 : DATA0, MIC Amplifier Gain 15dB, input channel 1 select (input channel 2 off) 		      
   	}	
   	// Record & play simultaneously
	if(mode == RECORD_PLAY_SIM)
	{
		_WrL3Addr(0x14 + 2);     //STATUS (000101xx+10)
   		_WrL3Data(0xa3,0);       // 1,0,1,0,0,0,11 : OGS=0,IGS=1,ADC_NI,DAC_NI,sngl speed,AonDon

   		_WrL3Addr(0x14 + 0);     //DATA0 (000101xx+00)
   		_WrL3Data(0xc2,0);       //11000,010  : DATA0, Extended addr(010) 
   		_WrL3Data(0xff,0);       //010,011,01 : DATA0, MS=9dB, Ch1=on Ch2=on
	}
}


unsigned int IIS_Select_SamplingRate(void)
{
	int i;
	
	printf("\nSelect ADC/DAC Rate\n");
	printf("0:11.025kHz, 1:22.05kHz, 2:44.1kHz, 3:88.2kHz\n");
	printf("4:8kHz, 5:16kHz, 6:32kHz, 7:48kHz, 8:64kHz, 9:96kHz\n");
	i = GetIntNum();	


	switch(i)
    {
		case 0:
    		return 11025;
		case 1:
    		return 22050;
       	case 2:
			return 44100;
       	case 3:
			return 88200;
       	case 4:
			return 8000;
       	case 5:
			return 16000;
       	case 6:
			return 32000;
       	case 7:
			return 48000;
       	case 8:
			return 64000;
       	case 9:
			return 96000;
       	default:
			return 44100;
	}      
}


// IIS source clock selection
void Select_PCLK(void)
{
	unsigned int pdf = 5; // prescaler division factor
	
	// SYSCON register setting
	rPCLKCON |= (1<<9); // PCLK bus block of i2s enable
	rSCLKCON |= (1<<9); // I2S source clock enable
	rCLKDIV1 &= ~(0xf<<12);	// I2S clock divider for EPLL.
	
	// IIS clock register setting
	rIISMOD = (rIISMOD & ~(7<<10)) | (0<<12)|(0<<10); // internal codec clock source, PCLK Master mode
	rIISPSR = (1<<15)|(pdf);  // prescaler enable, prescaler division factor[9:0]
		
	//In case PCLK = 50 MHz, IIS Codec CLK = 50/(5+1) = 8.34MHz-->22KHz
	printf("\nIIS Master CLK(PCLK) = %4.2f MHz", (float)PCLK/1000000);
	IIS_Codec_CLK = (float)PCLK/(pdf+1);
	printf("\nIIS Codec CLK = %4.2f MHz", IIS_Codec_CLK/1000000);

}


void Select_EXTCLK(void)
{
	unsigned int pdf = 0; // prescaler division factor
		
	printf("\n Board To Board Test Source Board is OK? \n");
	
	// SYSCON register setting
	rPCLKCON |= (1<<9); // PCLK bus block of i2s enable
	rSCLKCON |= (1<<9); // I2S source clock enable
	rCLKSRC = (rCLKSRC & ~(3<<14)) | (1<<14); // I2S first source clock selection
	rCLKDIV1 &= ~(0xf<<12);	// I2S clock divider for EPLL.
	
	// IIS clock register setting
	rIISMOD = (rIISMOD & ~(7<<10)) | (1<<12)|(1<<10); // Get Codec clock froem extenal codec chip, using codeclki master mode
	rIISPSR = (1<<15)|(pdf);  // prescaler enable, prescaler division factor[9:0]
			
}


void Select_EPLL(void)
{
	unsigned int pdf = 10; // prescaler division factor
	
	// SYSCON register setting
	rPCLKCON |= (1<<9); // PCLK bus block of i2s enable
	rSCLKCON |= (1<<9); // I2S source clock enable
	rEPLLCON= (40<<16) | (1<<8) | 1;	// EPLL OUT IS 96Mhz   : (Mdiv<<16) | (Pdiv<<8) | Sdiv;	
	rCLKSRC = (rCLKSRC & ~(3<<14)) | (0<<14); // I2S source clock selection EPLL divided clock
	rCLKSRC = (rCLKSRC & ~(1<<6)) | (1<<6); //   ESYSCLK Soure is divided EPlL clock
	rCLKDIV1 &= ~(0xf<<12);	// I2S clock divider for EPLL.
			
	Delay(100);
	
	rGPHCON = (rGPHCON & ~(3<<28)) | (2<<28);
	rMISCCR = (rMISCCR & ~(7<<8))  | (1<<8);
	printf("Check EPLL OUT!! and  Press Ant Key if You Want Go!!\n");
	getchar();
	
	// IIS clock register setting
	rIISMOD = (rIISMOD & ~(7<<10)) | (0<<12)|(1<<10); // internal codec clock source, EPLL Div Master mode
	rIISPSR = (1<<15)|(pdf);  // prescaler enable, prescaler division factor[9:0]

}


void Select_EPLL_Ref_CLK(void)
{
	unsigned int pdf = 1; // prescaler division factor	

	rPCLKCON |= (1<<9); // PCLK bus block of i2s enable	
	rSCLKCON |= (1<<9); // I2S source clock enable
	rEPLLCON= (1<<24) | (40<<16) | (1<<8) | 1;	// EPLL Off , EPLL OUT IS 96Mhz   : (Mdiv<<16) | (Pdiv<<8) | Sdiv;	
	rCLKSRC = (rCLKSRC & ~(3<<14)) | (3<<14); // I2S source clock selection EPLL reference clock
	rCLKSRC = (rCLKSRC & ~(1<<6)) | (0<<6); //   ESYSCLK Soure is divided EPlL clock
	rCLKDIV1 &= ~(0xf<<12);	// I2S clock divider for EPLL.
			
	Delay(100);
	
	rGPHCON = (rGPHCON & ~(3<<28)) | (2<<28);
	rMISCCR = (rMISCCR & ~(7<<8))  | (1<<8);
	printf("Check EPLL OUT!! and  Press Ant Key if You Want Go!!\n");
	getchar();
	
	// IIS clock register setting
	rIISMOD = (rIISMOD & ~(7<<10)) | (0<<12)|(1<<10); // internal codec clock source, EPLL Div Master mode
	rIISPSR = (1<<15)|(pdf);  // prescaler enable, prescaler division factor[9:0]

}


void Select_IIS_Master_CLK(void)
{
	int sel;
	//unsigned short Sampling_Rate;
	
    printf("\nSelect IIS Master Clock Source\n");
	printf("0:PCLK[D], 1:IIS EXTCLK, 2:EPLL, 3:EPLL Ref. CLK\n");
	sel = GetIntNum();		
	
	switch(sel)
	{
		case 0://In case of IIS Master Clock Source = PCLK
		Select_PCLK();
		break;
		
		case 1://In case of IIS Master Clock Source = EXTCLK Form GPIO (CDCLK input)
		Select_EXTCLK();
		break;

		case 2://In case of IIS Master Clock Source = divided EPLL or EPLL ref.
		Select_EPLL();
		break;

		case 3://In case of IIS Master Clock Source = EPLL Ref. CLK
		Select_EPLL_Ref_CLK();
		break;
		
		default : 
		Select_PCLK();	
		break;		
	}
}


// download wave files
void down_wav(void)
{
	//Non-cacheable area = 0x31000000 ~ 0x33cf0000
    Buf   = (unsigned char *)IIS_BUFFER;
    _temp = Buf;
    
    printf("Download the PCM(no ADPCM) file by DNW serial port(With header)!!\n");
    printf("Download address is %xh\n", Buf);
    while(((unsigned int)_temp - (unsigned int)Buf) < 4)
    {
       Led_Display(0);
       Delay(1500);
       Led_Display(15);
       Delay(1500);
    }
    printf("\ndata=%x",size);
      
    size = *(Buf) | *(Buf + 1)<<8 | *(Buf + 2)<<16 | *(Buf + 3)<<24;
    printf("\ndata=%x",size);
    
    printf("\nNow, Downloading... [ File Size : %8d(      0)]",size);
    while(((unsigned int)_temp - (unsigned int)Buf) < (size)){
	  printf("\b\b\b\b\b\b\b\b\b%8d)",(unsigned int)_temp - (unsigned int)Buf);
		Delay(5000);
    }
    printf("\b\b\b\b\b\b\b\b\b%8d)]\n",(unsigned int)_temp - (unsigned int)Buf);

    rINTSUBMSK |= BIT_SUB_RXD1;
    rINTMSK  |= BIT_UART1;
    size = *(Buf + 0x2c) | *(Buf + 0x2d)<<8 | *(Buf + 0x2e)<<16 | *(Buf + 0x2f)<<24;
    size = (size>>1)<<1;
    fs   = *(Buf + 0x1c) | *(Buf + 0x1d)<<8 | *(Buf + 0x1e)<<16 | *(Buf + 0x1f)<<24;

    printf("Sample Size = %d\n",size/2);
    printf("Sampling Frequency = %d Hz\n",fs);
    printf("\n[ Now play the wave file .....]\n");
    printf("If you want to mute or no mute push the 'EIN0' key repeatedly\n");
}


//=================================== [ IIS Test codes ] ==================================

⌨️ 快捷键说明

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