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

📄 cs1100_fm.c

📁 CS1100驱动 CS1100驱动 CS1100驱动 CS1100驱动 CS1100驱动 CS1100驱动
💻 C
字号:
/*****************************************************************************
*  Copyright Statement:
*  --------------------
*  This software is protected by Copyright and the information contained
*  herein is confidential. The software may not be copied and the information
*  contained herein may not be used or disclosed except with the written
*  permission of Cresilicon Technology Co.,Ltd (C) 2008
*
*****************************************************************************/

/*******************************************************************************
 * Filename: CS1100_FM_Tuner_Driver_Reference_Code_SW-Rev05.2.c
 * ------------
 * Project:
 * ------------
 * Description:
 * ------------
 * Author:
 * ------------
 * Revision History Rev02.0:   2008-03-14 Add Register Configuration of CS1100's reference clock seletion 
 * Revision History Rev03.0:   2008-03-21 modified in the functions of CS1100_FMInit and CS1100_FMSeekFromCurrentCh
 * Revision History Rev04.0:   2008-03-28 modified the initial value of registers
 * Revision History Rev05.1:   2008-04-10 modified the seek function; bool CS1100_FMSeek_TuneMethod(unsigned int TunerFrequency)--->bool CS1100_FMSeek_TuneMethod(unsigned int TunerFrequency, signed short *pryFD )			
 *					  Delete function: bool CS1100_FMSeekFromCurrentCh(bool seekUp, unsigned int *TunedFrequency,)
 *					  Add function: void CS1100_FM_SET_volume(unsigned int volume)
 * Revision History Rev05.2:   2008-04-11 Add some Judgements to eliminate issue channel which is a interfere frequency just in band [87.5MHZ~108MHZ]
 *					  
 *
 *
 *
 * ------------
 *******************************************************************************/

/*
********************************************************************************************
* Current Version: Rev05 for CS1100
* Description: the reference driver code describes I2C protocol between FM tuner and MCU 
* by GPIO method, and how to implement FM tuner power up/power down/tune/seek functions
********************************************************************************************
*/	


/**************************************************************************************
* macro definition for slave address of I2C protocol control, i.e. FM tuner address
**************************************************************************************/
#define CS1100_RD_CTRL   0x0021 
#define CS1100_WR_CTRL   0x0020 

#define SDA_HIGH  SDA=1 
#define SDA_LOW   SDA=0 

#define SCL_HIGH  SCL=1 
#define SCL_LOW   SCL=0

#define SDA_OUT 				//function to enable SDA pin output
#define SDA_IN 					//function to enable SDA pin input

#define ISSUE_CHANNEL 10400
unsigned int CS1100ControlData[26];

void  SetSDAState(unsigned int state) 
{
	SDA=(bool)(state);
}

unsigned int  GetSDAState(void)
{
	return (unsigned int)SDA;
}


/**************************************************************************************
* how to implement I2C protocol control between FM tuner and MCU of main chip by GPIO method
**************************************************************************************/
void DelayXus(unsigned int X)
{
	unsigned int i;
	for(i = X/2; i >= 1; i--)
		delay_nops(CurrCpuFreq);
}


void I2C_Start(void)
{
   SCL_HIGH;		
   SDA_HIGH;				
   DelayXus(1);
   SDA_OUT;																																

   DelayXus(50);
   SDA_LOW;
   DelayXus(30);
   SCL_LOW;
   DelayXus(20);
}

void I2C_Stop(void)
{
	SCL_LOW;
	SDA_LOW;
	DelayXus(2);
        SDA_OUT;
    
	DelayXus(2);
	SCL_LOW;
	SDA_LOW;
	DelayXus(10);
	SCL_HIGH;
	DelayXus(20);
	SDA_HIGH;
	DelayXus(20);
}

void I2C_SendAck(unsigned int ack)
{
	SetSDAState(ack);
   	DelayXus(1);
  	SDA_OUT;

  	SCL_HIGH;
  	DelayXus(20);
  	SCL_LOW;
  	DelayXus(20);
}

unsigned int  I2C_SendByte(unsigned int byte)
{
 	int i;
 	unsigned int ack = 0;
 	
 	SetSDAState(byte&0x80);  	
        SDA_OUT;
  
	DelayXus(10);
  	for(i=7;i>=0;i--)
	{
	  SetSDAState(byte&0x80);
		
	 	byte <<= 1;
	  DelayXus(20);
	  
	  SCL_HIGH;
	  DelayXus(40);
	  
	  SCL_LOW;
	  DelayXus(20);
	}
  
  	SDA_IN;
  	DelayXus(10);
  
  	SCL_HIGH;
  	DelayXus(40);		
 	ack=GetSDAState();
  	SCL_LOW;
 	DelayXus(40);
  	return ack;
}

unsigned int I2C_ReadByte(void)
{
 	int i;
 	unsigned int byte = 0;
 	SDA_IN;
 	DelayXus(10);
 	for(i=7;i>=0;i--)
	{
	   SCL_HIGH;
	   DelayXus(20);

	  byte <<= 1;
	  byte |= GetSDAState();
	  DelayXus(20);
	  
	  SCL_LOW;
	  DelayXus(40);
	}
  	return byte;
}

unsigned int  I2C_ReadCS1100Reg(unsigned int *data,unsigned int size)	//state=0->success  state=1->fail 
{
  	unsigned int i,state = 0;
  	I2C_Start();
  	if(I2C_SendByte(CS1100_RD_CTRL))
  	{
	  state = 1;
	  goto I2C_STOP;
  	}

  	for(i=0;i<size-1;i++)
	{
	  data[i] = I2C_ReadByte();
	  I2C_SendAck(0);
	}
   	data[i] = I2C_ReadByte();
   	I2C_SendAck(1);
  
 I2C_STOP:
	 I2C_Stop();
	 return state;
}

unsigned int I2C_WriteCS1100Reg(unsigned int *data,unsigned int size) //state=0->success  state=1->fail
{
	unsigned int i,state = 0;;
	I2C_Start();
	if(I2C_SendByte(CS1100_WR_CTRL)) 
	  {
	    state = 1;
	    goto I2C_STOP;
	  }
        for(i=0;i<size;i++)
	{
	   if(I2C_SendByte(data[i]))
	   	{
	   	 state = 1;
		 break;
	   	}
	}
	
I2C_STOP:
       I2C_Stop();
       return state;
}



/**************************************************************************************
* how to implement FM tuner initialization/tune/seek/stereo indicator functions
**************************************************************************************/


/**************************************************************************************
*   函数名称:CS1100_FMInit
*   功    能:
*   输入参数:
*   输出参数:
*   说    明:FM power up and initialization operation
**************************************************************************************/
void CS1100_FMInit(void)
{	
	// initial default value of CS1100 READ/WRITE registers 03h~0Eh
  	CS1100ControlData[0]  = 0xe4;  
  	CS1100ControlData[1]  = 0xd8;
  	CS1100ControlData[2]  = 0x3e;
  	CS1100ControlData[3]  = 0x26;
	CS1100ControlData[4]  = 0x1f; 			
	CS1100ControlData[5]  = 0x80; 
	CS1100ControlData[6]  = 0x38;   
				  	 			  	         
												   				  				
	CS1100ControlData[7]  = 0x53;
	CS1100ControlData[8]  = 0xb3;
	CS1100ControlData[9]  = 0xb3;
	CS1100ControlData[10] = 0xaa;
	CS1100ControlData[11] = 0xf0;  
	CS1100ControlData[12] = 0x8b;
	CS1100ControlData[13] = 0xaa;   
	CS1100ControlData[14] = 0xc0;
	CS1100ControlData[15] = 0x04; //
	CS1100ControlData[16] = 0x25;
	CS1100ControlData[17] = 0x35;
	CS1100ControlData[18] = 0xff;
	CS1100ControlData[19] = 0xfd;
	CS1100ControlData[20] = 0x92; 
	CS1100ControlData[21] = 0x0f;
	CS1100ControlData[22] = 0x44;
	CS1100ControlData[23] = 0x00;
	CS1100ControlData[24] = 0x84;
	CS1100ControlData[25] = 0x50;
	
	//*******************************************************
	//Reference clock is from 32.768KHz external clock input: 外灌时钟  
	CS1100ControlData[6]  = 0x28;  
	CS1100ControlData[15] = 0x00; 
	
	//Reference clock is from 13MHz     external clock input:  外灌时钟
	CS1100ControlData[6]  = 0x68;  
	CS1100ControlData[15] = 0x00;
	
	//Reference clock is from 32.768KHz  crystal oscillator  :  晶体
	CS1100ControlData[6]  = 0x38;  
	CS1100ControlData[15] = 0x04;

        //******************************************************

	
	CS1100ControlData[0] &= 0x7f; //power up
	I2C_WriteCS1100Reg(CS1100ControlData,26);		
	Delay1Ms(1000); // wait 1s for crystal oscillate stable

	CS1100ControlData[0] &= 0xdf;  // mute off
	I2C_WriteCS1100Reg(CS1100ControlData,1);	
	
}


/**************************************************************************************
*   函数名称:CS1100_FMTune
*   功    能:
*   输入参数:TunerFrequency, the unit is 10kHz
*   输出参数:
*   说    明:Tune to certain frequency and output audio
**************************************************************************************/
void CS1100_FMTune(unsigned int TunerFrequency) // 频率转换参数 87.5 ==>8750
{
	unsigned int ch = 0;

	// frequency transfer to channel number,  channel=(frequencyMhz-60)/0.05, e.g. 87.5Mhz->550
	ch = (TunerFrequency - 6000)/5; 

	// set channel number 
	CS1100ControlData[2] &= 0xfc;
	CS1100ControlData[2] |= (ch & 0x0300)>>8;
	CS1100ControlData[3] =	ch & 0xff;
	//

	// tune function
	CS1100ControlData[0] &= 0xdf;// mute off
	CS1100ControlData[0] &= 0xfd;// tune=0
	I2C_WriteCS1100Reg(CS1100ControlData,4);

	CS1100ControlData[0] |= 0x02;//tune=1, begin tune operaton
	I2C_WriteCS1100Reg(CS1100ControlData,1);
	Delay1Ms(100); // wait for 100ms

}    


/**************************************************************************************
*   函数名称:CS1100_FMSeek_TuneMethod
*   功    能:
*   输入参数:unsigned int TunerFrequency, the frequency unit is 10kHz           
*   输出参数:bool seekover, return the indicator if the seek operation is completed
*	      signed short *pryFD,return current channel's fd
*   说    明:seek operation with tune method step by step, judge the threshold by the software
**************************************************************************************/
bool CS1100_FMSeek_TuneMethod(unsigned int TunerFrequency, signed short *pryFD)
{
	unsigned int ch = 0;
        unsigned int snr,rssi,st,loop;
	signed short fd;
	bool seekover, stcflag;
        unsigned int Temp[27] = { 0x00 };

	// frequency transfer to channel number,  channel=(frequencyMHz-60)/0.05, e.g. 87.5Mhz->550
	ch = (TunerFrequency - 6000)/5;
	CS1100ControlData[2] &= 0xfc;
	CS1100ControlData[2] |= (ch & 0x0300)>>8;
	CS1100ControlData[3] =	ch & 0xff;

	// seek operation
	CS1100ControlData[0] |= 0x20; //mute on
	CS1100ControlData[0] &= 0xfd; //tune=0
	I2C_WriteCS1100Reg(CS1100ControlData,4);
	
	CS1100ControlData[0] |= 0x02; // TUNE=1, begin tune operation
	I2C_WriteCS1100Reg(CS1100ControlData,1);
	Delay1Ms(50); // delay 50ms - 100ms

	// read STC indicator and judgement of seek threshold
	seekover=0;
	stcflag=0;
	
	loop=0;
        do
	{
	    I2C_ReadCS1100Reg(Temp,6);		  
            stcflag=Temp[0]&0x04; // STC bit
   
            loop++;
	    Delay1Ms(1); // delay 1ms
   	}while((!stcflag)&&(loop!=0x1f));

	
    if(stcflag)  //STC=1
    {   
        rssi=Temp[1];
	snr=Temp[2]/4;	 	 
        fd=Temp[5];
        st=Temp[0]&0x01;
         
			    
        if(fd>127)
        {
           fd=fd-256;	 		
        }  
		
        if(rssi>=176 && snr<=38 && ( fd<=10 && fd>=(-10) )) //seek threshold judgement
        {
        	if(*pryFD <= -30)  //Note seek direction is seek up
	        {
	          	if(TunerFrequency == 9600 || TunerFrequency == 10400)  
	          	{
		        	if (st==0x01)     //Note: now Reg03[6] must be set 0  
		          	      seekover=1; //a valid frequency 
		          	else  
		          	      seekover=0; //a invalid frequency
	          	}
	          	else 
	          		seekover=1;
	        }
		else
	          	seekover=0;
        }
        else
        {
          	seekover=0;
        }

        *pryFD = fd; //save current frequency's fd
	   
     }
	 
	return seekover;
}


/**************************************************************************************
*   函数名称:CS1100_FMPowerdown
*   功    能:
*   输入参数:
*   输出参数:
*   说    明:power down chip
**************************************************************************************/
void CS1100_FMPowerdown(void)
{
	CS1100ControlData[0] |= 0x20;  // mute on
	CS1100ControlData[0] |= 0x80;  // power down
	I2C_WriteCS1100Reg(CS1100ControlData,1);	
}


/**************************************************************************************
*   函数名称:CS1100_FM_PAMode
*   功    能:CS1100从FM Tuner模式进入LINE-IN PA模式
*   说    明:需要先初始化FM Tuner寄存器
**************************************************************************************/
void CS1100_FM_PAMode(void)
{
	//旧步骤
//	CS1100ControlData[2]  |= 0x80; // line-in PA mode on
//	CS1100ControlData[14] |= 0x38; // power down not used blocks 
//	CS1100ControlData[15] |= 0x68; // power down not used blocks 		
//	I2C_WriteCS1100Reg(CS1100ControlData,16);

	// 新步骤
	CS1100ControlData[2]  |= 0x40;         //pa off,minimun volume 
	CS1100ControlData[0]  & =0xbf;         //Analog Config
	I2C_WriteCS1100Reg(CS1100ControlData,3);
	
	CS1100ControlData[0] &= 0x7f;          //power on
	I2C_WriteCS1100Reg(CS1100ControlData,1);
	
	Delay1Ms(1000);
	
	CS1100ControlData[2] &= 0xbf;         //pa on
	I2C_WriteCS1100Reg(CS1100ControlData,3);
	Delay1Ms(50);
	
	CS1100ControlData[2] |= 0x80;	     //line in mode
	CS1100ControlData[0] |=0x20;        //mute on
	I2C_WriteCS1100Reg(CS1100ControlData,3);

	CS1100ControlData[14] |= 0x39;      //cut down the current
	CS1100ControlData[15] |= 0xf8; 
	I2C_WriteCS1100Reg(CS1100ControlData,16);
	
	//CS1100ControlData[0] |= 0xc0;           //power off ??
	//I2C_WriteCS1100Reg(CS1100ControlData,1);
}


/**************************************************************************************
*   函数名称:CS1100_FM_TunerMode
*   功    能:CS1100从LINE-IN PA模式恢复到FM Tuner模式
*   说    明:需要先初始化FM Tuner寄存器
**************************************************************************************/
void CS1100_FM_TunerMode(void)
{
	//旧步骤
//	CS1100ControlData[2]  &= 0x7f; // line-in PA mode off
//	CS1100ControlData[14] &= 0xc7; // power on blocks 
//	CS1100ControlData[15] &= 0x97; // power on blocks 		
//	I2C_WriteCS1100Reg(CS1100ControlData,16);	

        //新步骤
	CS1100ControlData[2] |= 0x40; //PA off,minimun volume
	CS1100ControlData[0] |= 0x40; 

	CS1100ControlData[14] &= 0xCB; //Power up DSP
	CS1100ControlData[15] &= 0x07;
	I2C_WriteCS1100Reg(CS1100ControlData,16);

	CS1100ControlData[0]  &= 0x7f; //power on
	I2C_WriteCS1100Reg(CS1100ControlData,1);
	Delay1Ms(1000);
	
	CS1100ControlData[2] &= 0xbf; //volume
	I2C_WriteCS1100Reg(CS1100ControlData,3);
	Delay1Ms(50);
	
	CS1100ControlData[2] &= 0x7f;//fm mode
	I2C_WriteCS1100Reg(CS1100ControlData,3);
}

/**************************************************************************************
*   函数名称:CS1100_FM_SET_volume
*   功    能:
*   输入参数:unsigned int volume
*   输出参数:
*   说    明:Set CS1100 FM Volume
**************************************************************************************/
void CS1100_FM_SET_volume(unsigned int volume)
{
	unsigned int temp;
	if(volume > 0x0f)
	{
	   volume = 0x0f;			
	}
			
	CS1100ControlData[2]&= 0xc3;  //0xc3=11000011
	temp = volume<<2;
	temp &= 0x3c; //0x3c=00111100
	CS1100ControlData[2] |= temp;
	I2C_WriteCS1100Reg(CS1100ControlData,3);			
}

⌨️ 快捷键说明

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