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

📄 pcm.c

📁 三星s3c2460开发板完整功能测试代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************************

	File Name: pcm.c

	Description: S3C2460 PCM Audio Interface Function Test Code
	Version: 0.0
	
       History:
             0.0: 2004. 07. 07, First draft, programmed and tested by Yoh-Han Lee 
                 - This S3C2460 PCM test code works with AK2430 PCM Codec on the SMDK2460. 
                 - Test of AK2430 IIC Interface with S3C2460 is supported. 
                 - PCM In/Out in DMA mode is supported. 
                 - PCM In/Out in interrupt mode is supported. Thanks to Rader.
                                           
********************************************************************************/

#include <stdlib.h>
#include <string.h>
#include "option.h"
#include "type.h"

#include "2460addr.h"
#include "2460lib.h"
#include "2460slib.h"

#include "pcm.h"
#include "PLL.h"

//#define PCM_REC_LEN 0xfffff*2	//Max value of DMA Transfer Counter (20bit) = 0xfffff, Date Size=Half word (2bytes)
#define PCM_REC_LEN 0x3ffff*2

//org
//#define DOWN_BUF 0x11000000		//_NONCACHE_STARTADDRESS
//khs(050909)
#define DOWN_BUF _NONCACHE_STARTADDRESS		//_NONCACHE_STARTADDRESS

#define PCM_OUT_Threshold 16
#define PCM_IN_Threshold 16

unsigned int save_PCM_rGPICON, save_PCM_rGPIDAT, save_PCM_rGPIUP;
unsigned int PCM_size, PCM_fs;

unsigned short *Rec_PCM_BUF, *End_PCM_BUF, *Play_PCM_BUF;
volatile short PCM_Out_INT_Exit = 0;
volatile short PCM_In_INT_Exit =0;

unsigned char *PCM_BUF,*PCM_temp;
unsigned char Exit_Key;

volatile char PCM_Rec_Done = 0;

void AK2430_IIC_Write(unsigned int slvAddr,unsigned int addr,unsigned char data);   
unsigned char   AK2430_IIC_Read(unsigned int slvAddr,unsigned char addr);  

void PCM_Port_Init(void);
void PCM_Port_Return(void);

void AK2430_CodecInit_PCMOut(void);
void AK2430_CodecExit_PCMOut(void);

void AK2430_CodecInit_PCMIn(void);
void AK2430_CodecExit_PCMIn(void);

void PCM_PCMout_DMA1(unsigned int PCM_Size);
void PCM_PCMin_DMA2(unsigned int PCM_Size);
void PCM_PCMout_INT(unsigned int PCM_Size);
void PCM_PCMin_INT(unsigned int PCM_Size);

static void __irq DMA1_Play_Done(void);
static void __irq DMA2_Rec_Done(void);
void __irq Irq_PCM_PCMout(void);
void __irq Irq_PCM_PCMin(void);

void * func_pcm_test[][2]=
{	
	//PCM Function Test Item
    	(void *)PCM_Codec_IIC_Test,	"PCM Codec IIC Test   ",  
	(void *)PCM_In_Out_Test,     	"Record Sound and Play it through PCM Codec. ",   
    	 0,0
};

void PCM_Test(void)
{
	
	int i;
	
	while(1)
	{
		i=0;
		printf("\n\n========================= PCM Function Test ==========================\n\n");

		while(1)
		{   //display menu
			printf("%2d:%s",i,func_pcm_test[i][1]);
			i++;
			if((int)(func_pcm_test[i][0])==0)
			{
				printf("\n");
				break;
			}
			if((i%2)==0)
			printf("\n");
		}

		printf("\n======================================================================");
		printf("\nSelect #Item or Press enter key to exit:");
		i = GetIntNum();
			
		if(i==-1) break;		// return.	
		if(i>=0 && (i<(sizeof(func_pcm_test)/8)) )	// select and execute...
			( (void (*)(void)) (func_pcm_test[i][0]) )();
	}
		
}


//Top Level PCM Test Functions
void PCM_Codec_IIC_Test(void)
{
	unsigned int i;

    	printf("\nIIC Test of AK2430 PCM Codec.\n");

	printf("\nReg. Addr.	Reg. Data\n");	

	for(i=0x2; i<0x1f; i++)
	{
       	printf("0x%02x		0x%02x \n", i, AK2430_IIC_Read(0x9e, i));		
	}

	for(i=0;i<32;i++)
	{
		AK2430_IIC_Write(0x9e, 0x15, i);
       	printf("MASTERVOL: %2d \n", AK2430_IIC_Read(0x9e, 0x15));		
	}
	
}

//*khs. added for mode selection
uint8 pcm_mode=1;
void PLL_Change(uint8 mode)
{
	PreChangeSDRAMParameter();
	
	if(pcm_mode==0)
	{
		
		SetCLKDIV(1,1,0);
		//*khs. ARM=256MHz, Hclk=128MHz, Pclk=64MHz
		SetMPLL( 120, 1, 1);
		
	}
	else
	{
		SetMPLL( Startup_MDIV, Startup_PDIV, Startup_SDIV);
		SetCLKDIV( Startup_ARMCLKdiv, Startup_HCLKdiv, Startup_PCLKdiv);
	}
	
	GlobalCLK();
	Init_LogicalConsole();
	
	ChangeSDRAMParameter(HCLK);
	
	Delay(100);
	return;
}

void PCM_In_Out_Test(void)
{
	int i;
	
	PCM_Port_Init();

	printf("\nSelect PCM In/Out Operation Mode\n");
	printf("0: Interrupt, 1: DMA\n");
	i = GetIntNum();
	//->
	//khs.050516
	//	added for selecting master or slave mode
	printf("\nSelect Record Mode\n");
	printf("0: Master Mode, 1: Slave Mode\n");
	pcm_mode=GetIntNum();
	PLL_Change(pcm_mode);
	//<-	

	switch(i)
       {
   		case 0://Interrupt Mode 
   		//PCM In
		AK2430_CodecInit_PCMIn();
			PCM_PCMin_INT(PCM_REC_LEN/8);
			AK2430_CodecExit_PCMIn();

			//->
			//khs.050516
			//	added for selecting master or slave mode
			printf("\nSelect Play Mode\n");
			printf("0: Master Mode, 1: Slave Mode\n");
			pcm_mode=GetIntNum();
			PLL_Change(pcm_mode);
			//<-

			//PCM Out 
			AK2430_CodecInit_PCMOut();
			PCM_PCMout_INT(PCM_REC_LEN/8);	
		break;

		case 1://DMA Mode 
		//PCM In
		AK2430_CodecInit_PCMIn();
		PCM_PCMin_DMA2(PCM_REC_LEN/8);
		AK2430_CodecExit_PCMIn();

			//->
			//khs.050516
			//	added for selecting master or slave mode
			printf("\nSelect Play Mode\n");
			printf("0: Master Mode, 1: Slave Mode\n");
			pcm_mode=GetIntNum();
			PLL_Change(pcm_mode);
			//<-

		//PCM Out 
		AK2430_CodecInit_PCMOut();
		PCM_PCMout_DMA1(PCM_REC_LEN/8);
		break;

              default:
              break;

	}
	
	AK2430_CodecExit_PCMOut();	
	
	PCM_Out_INT_Exit = 0;
	PCM_In_INT_Exit =0;

	PCM_Port_Return();
}


// Functional Sub-Routines
void PCM_Port_Init(void)
{
	//Push PCM GPIO port configuration
	save_PCM_rGPIDAT=rGPIDAT;
	save_PCM_rGPICON=rGPICON; 
	save_PCM_rGPIUP=rGPIPU;
	
	//---------------------------------------------------------------------
	//PORT E GROUP
	//Ports  :  GPA4    		 GPA3             GPA2            GPA1                GPA0 
	//Signal :  PCM SYNC   PCM SDO     PCM SDI      PCM RESETn    PCM BITCLK 
	//Binary :  11,               11,                11,                11,                   11    
	//---------------------------------------------------------------------
	
	rGPICON = rGPICON & ~(0xffc0000) | 0xaa80000;   
	rGPIPU  = rGPIPU  & ~(0x3e00)  | 0x3e00;    
}

void PCM_Port_Return(void)
{
	//Pop PCM GPIO port configuration
	rGPICON=save_PCM_rGPICON; 
	rGPIDAT=save_PCM_rGPIDAT;
	rGPIPU=save_PCM_rGPIUP;
}

////PCM Codec Register Setting for Out-Operation 
void AK2430_CodecInit_PCMOut(void)
{
	AK2430_IIC_Write(0x9e, 0x18, 0x07);	//MSTCLK_I = 19.2MHz
	//->
	//khs.050516
	//	modified for mode selection
	#if 1	//new>>
	if(pcm_mode==0)
		AK2430_IIC_Write(0x9e, 0x1B, 0xC);	//external PCM Codec Slave Mode
	else
		AK2430_IIC_Write(0x9e, 0x1B, 0x0);	//external PCM Codec Master Mode
	#else	//org>>
	AK2430_IIC_Write(0x9e, 0x1B, 0x0);	//external PCM Codec Master Mode
	#endif
	//<-
       AK2430_IIC_Write(0x9e, 0x1E, 0x01);	//DLCK = 256kHz, 14bit linear code (2's complement  format)

       AK2430_IIC_Write(0x9e, 0x0C, 0x0);	//0 dB
       AK2430_IIC_Write(0x9e, 0x10, 0x1F);	//three dB
       AK2430_IIC_Write(0x9e, 0x11, 0x1F);    //three dB
       AK2430_IIC_Write(0x9e, 0x06, 0x40);	//POP Mute Off
     

       AK2430_IIC_Write(0x9e, 0x03, 0x01);	//CKI Buff On other blocks Off
       Delay(1);
       
	AK2430_IIC_Write(0x9e, 0x03, 0x09);	//PLL2, CKI Buff On and other blocks Off
       Delay(300);

	AK2430_IIC_Write(0x9e, 0x04, 0x01);	//RXSUM On and other blocks Off
	AK2430_IIC_Write(0x9e, 0x05, 0x20);	//PCM Codec On and other blocks Off
       Delay(50);

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

       AK2430_IIC_Write(0x9e, 0x04, 0x31);	//EPL/R Amp(RXSUM) On and other blocks Off
       Delay(1600);
       
}


void AK2430_CodecExit_PCMOut(void)
{
	AK2430_IIC_Write(0x9e, 0x04, 0x01);	//EPL/R Amp Off		
	Delay(1300);

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

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


//PCM Codec Register Setting for In-Operation 
void AK2430_CodecInit_PCMIn(void)
{
	AK2430_IIC_Write(0x9e, 0x18, 0x07);	//MSTCLK_I = 19.2MHz
	//Transfer data enable  
	//->
	//khs.050516
	//	modified for mode selection
	#if 1	//new>>
	if(pcm_mode==0)
		AK2430_IIC_Write(0x9e, 0x1B, 0xC);	//external PCM Codec Slave Mode
	else
		AK2430_IIC_Write(0x9e, 0x1B, 0x0);	//external PCM Codec Master Mode
	#else	//org>>
	AK2430_IIC_Write(0x9e, 0x1B, 0x0);	//external PCM Codec Master Mode
	#endif
	//<-

	AK2430_IIC_Write(0x9e, 0x1E, 0x01);	//DLCK = 256kHz, 14bit linear code (2's complement  format)

	AK2430_IIC_Write(0x9e, 0x0D, 0x5);	//0 dB
	AK2430_IIC_Write(0x9e, 0x06, 0x40);	//POP Mute Off

	AK2430_IIC_Write(0x9e, 0x03, 0x01);	//CKI Buff On other blocks Off
	Delay(1);

	AK2430_IIC_Write(0x9e, 0x03, 0x09);	//PLL2, CKI Buff On and other blocks Off
	Delay(300);

	AK2430_IIC_Write(0x9e, 0x05, 0x10);	//TXSUM On and other blocks Off
	AK2430_IIC_Write(0x9e, 0x05, 0x30);	//PCM Codec, TX Sum On and other blocks Off
	Delay(50);

	AK2430_IIC_Write(0x9e, 0x0B, 0x11);	//sw_COI, sw_TX1 Close and other sw Open
	AK2430_IIC_Write(0x9e, 0x05, 0x35);	//MIC AMP1, MIC BIAS1, PCM CODEC, TX SUM On and other bolcks OFF
	Delay(1600);
       
}


void AK2430_CodecExit_PCMIn(void)
{
	AK2430_IIC_Write(0x9e, 0x05, 0x30);	//MIC Amp1, MIC Bias1 Off	
	Delay(1300);
	
	AK2430_IIC_Write(0x9e, 0x0B, 0x00);	//sw_COI, sw_TX1 Open	
	AK2430_IIC_Write(0x9e, 0x05, 0x00);	//TX SUM, PCM Codec Off
}


//////////////////////////////////////////////////////////////////////////
void PCM_PCMout_DMA1(unsigned int PCM_Size)
{
	unsigned int i;
	
	//pISR_EINT0= (unsigned)Muting;
	pISR_DMA_SBUS= (unsigned)DMA1_Play_Done;

	ClearPending(BIT_DMA_SBUS);	
	rSUBSRCPND=(BIT_SUB_DMA1);

	rINTMSK = ~(BIT_DMA_SBUS);
	rINTSUBMSK=~(BIT_SUB_DMA1);
	
	Play_PCM_BUF=(unsigned short *)DOWN_BUF;

	//*Play_PCM_BUF= 0x50f0;

	//PCM  Initialize
	printf("\nConnect head-phone plug into speaker-out socket on SMDK2460 and Press any key.\n");
	getchar();
	printf("\nNow Play...\n");
	printf("\nIf you want to exit, Press the 'x' key.\n");
	
	//DMA Ch1 for PCMInitialize
	rDISRC1  = (unsigned)Play_PCM_BUF;                 
	rDISRCC1 = (0<<1) + (0<<0);		//The source is in the system bus(AHB), Increment      
	rDIDST1  = 0x46200008;  	//PCM Out Data Fifo    
	rDIDSTC1 = (1<<1) + (1<<0);           //The destination is in the peripheral bus(APB), Fixed  
	rDCON1   = (0<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(0<<22)+(1<<20)+(PCM_Size/2);
	rDMASKTRIG1 = (0<<2) + (1<<1) + (0<<0);          //No-stop[2], DMA1 channel On[1], No-sw trigger[0] 
	rDMAREQSEL1 = (4<<1) + (1<<0); 


	//Transfer data enable  
	//->
	//khs.050516
	//	modified for mode selection
	#if 1	//new>>
	if(pcm_mode==0)
		rPCM_CLKCTL = (1<<19) | (1<<18) | (124<<9) |(31<<0);
	else

⌨️ 快捷键说明

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