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

📄 cs1100_drv.c

📁 MTK cresilicon FM IC
💻 C
字号:

                                                

#include "l1audio_def.h"

#if (defined(CS1100)) 

#define READ	1
#define WRITE	0

#define CS1100_WR_CTRL 0x20
#define CS1100_RD_CTRL 0x21

uint8 CS1100ControlData[26];
  
/* Serial communication interfaces */
void SerialCommInit(void);
void SerialCommRelease(void);
void SerialCommCryClkOn(void);
void SerialCommCryClkOff(void);
void SerialCommRxByte(uint8 *data, uint8 ack);
uint8 SerialCommTxByte(uint8 data);
void SerialCommStop(void);
void SerialCommStart(void);


void   CS1100_Delay_ms(kal_uint32 times)
{
	kal_uint32 delay1;
	kal_uint16   delay2;
       for(delay1=0;delay1<times;delay1++)
	   	 for(delay2=0;delay2<4700;delay2++){ }  // about 1ms
}



unsigned int  CS1100_I2C_ReadCS1100Reg(uint8 *data,uint8 size)	//state=0->success   
{									//state=1->fail
  	unsigned int i,state = 0;
	SerialCommInit();
  	SerialCommStart();
  	if(SerialCommTxByte(CS1100_RD_CTRL))
  	{
 	  state = 1;
	  goto I2C_STOP;
  	}

  	for(i=0;i<size-1;i++)
	{
	   SerialCommRxByte(&data[i],0 );
	}

	SerialCommRxByte(&data[i],1);
I2C_STOP:
	SerialCommStop();
    SerialCommRelease();	 
	return state;
}

unsigned int CS1100_I2C_WriteCS1100Reg(uint8 *data,uint8 size) //state=0->success  
{								      //state=1->fail
	unsigned int i,state = 0;;
	SerialCommInit();
  	SerialCommStart();
	if(SerialCommTxByte(CS1100_WR_CTRL)) 
	{ 
	    state = 1;
	    goto I2C_STOP;
	}

    for(i=0;i<size;i++)
	{
	   if(SerialCommTxByte(data[i]))
	   	{
	   	 state = 1;
		 break;
	   	}
	}

I2C_STOP:
    SerialCommStop();
    SerialCommRelease();
    return state;
}


bool CS1100_FMInit(void)
{
	unsigned char error_ind = 0;
	
	// initial default value of CS1100 READ/WRITE registers 03h~0Eh
  	CS1100ControlData[0] = 0xe4;  
  	CS1100ControlData[1] = 0xd8;   
  	CS1100ControlData[2] = 0x7e; // internal  PA OFF, 0x3e->internal  PA ON
  	CS1100ControlData[3] = 0x26;
	CS1100ControlData[4] = 0x1f; 			
	CS1100ControlData[5] = 0x80; 
	CS1100ControlData[6] = 0x28; //CS1100ControlData[6] = 0x38; // for 32.768k crystal
	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] = 0x00; //CS1100ControlData[15] = 0x04;//for 32.768k crystal
	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;

	#if 0
	CS1100ControlData[2] &= 0xfc;
	CS1100ControlData[2] |= (924 & 0x0300)>>8;
	CS1100ControlData[3] =	924 & 0xff;
    CS1100ControlData[0] |= 0x02; // TUNE=1                   
	CS1100ControlData[0] &= 0xdf;  // mute off
	#endif
	
	error_ind = CS1100_I2C_WriteCS1100Reg(CS1100ControlData,26);	

	if (error_ind )
		return 0;
	else
		return 1;
}

void CS1100_FMTune(unsigned int TunerFrequency)
{
	unsigned int ch = 0;
	#if 0
	kal_uint8 Temp[10];
	unsigned int rssi, snr, fd;
	#endif

    // 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] &= 0xfe;  // seek=0 
	CS1100ControlData[0] &= 0xdf;  // mute off
	CS1100ControlData[0] &= 0xfd;  // tune=0
	CS1100_I2C_WriteCS1100Reg(CS1100ControlData,4);

    
	CS1100ControlData[0] |= 0x02;  // tune=1
	CS1100_I2C_WriteCS1100Reg(CS1100ControlData,1);
	CS1100_Delay_ms(100); // wait for 100ms

	#if 0
	CS1100_I2C_ReadCS1100Reg(Temp,10);
		rssi=Temp[1];
		snr=Temp[2]/4;	 	 
		fd=Temp[5]; 
         kal_prompt_trace(MOD_MM, "temp is %x,%x \n", Temp[0],Temp[1]);
		 kal_prompt_trace(MOD_MM, "tune ch,rssi,snr,fd=%d,%d,%d,%d \n",ch,rssi,snr,fd);
	#endif
	
}    


uint8  CS1100_FMSeek_Software(bool seekUp, int16 Frequency)
{
	static int  prefd=-50, preHLSI=0;

	// local variable
	unsigned int ch = 0;
	unsigned int snr,fd,rssi,fd_abs,loop;
	int  fd_comp;
	bool stcflag;
	bool hlsi;
	bool st;
	bool fdstate=0;
	kal_uint8 Temp[10];
	

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

	// tune function
	CS1100ControlData[0] &= 0xfe;  // seek=0 
	CS1100ControlData[0] &= 0xfd;  // tune=0
	CS1100_I2C_WriteCS1100Reg(CS1100ControlData,4);
    

	CS1100ControlData[0] |= 0x02;  // tune=1
	CS1100_I2C_WriteCS1100Reg(CS1100ControlData,1);
	CS1100_Delay_ms(50); // wait for 50ms

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


    #if 0
    //CS1100_I2C_ReadCS1100Reg(Temp,10);
    kal_prompt_trace(MOD_MM, "Temp=%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n",Temp[0],Temp[1],Temp[2],Temp[3],Temp[4],Temp[5],Temp[6],Temp[7],Temp[8],Temp[9]);
    #endif
    
	
	if(!stcflag)  //STC=0
	{
	    //kal_prompt_trace(MOD_MM, "STC error\n");
		return 0; // it's error
		
	}

	// read hlsi, rssi, snr, fd, st
	st = Temp[0]& 0x01;
	hlsi = Temp[0]&0x08;
	rssi=Temp[1];
	snr=Temp[2]/4;	 	 
	fd=Temp[5];     	 	 	 
	if(fd>127)
	{
		fd_comp=fd-256; 
		fd_abs=256-fd;
	}
	else
	{
		fd_abs=fd;
		fd_comp=fd;
	}


	if(seekUp)
	{
	if(preHLSI) 
	{
		if(-prefd<=-20) // prefd inverse
		{
			fdstate=1;
		}
		else
		{
			fdstate=0;
		}
		
	}
	else
	{
		if(prefd<=-20)
		{
			fdstate=1;
		}
		else
		{
			fdstate=0;
			
		}
		
	}
	}
	else
	{
	if(preHLSI) 
	{
		if(-prefd>=20) // prefd inverse
		{
			fdstate=1;
		}
		else
		{
			fdstate=0;
		}
	}
	else
	{
		if(prefd>=20)
		{
			fdstate=1;
		}
		else
		{
			fdstate=0;
		}
		
	}
	}		

	#if 0
	
    kal_prompt_trace(MOD_MM, "seek is %d,%d,%d,%d,%d,%d,%d \n", Frequency,ch,rssi,snr,fd_abs,fd_comp,prefd);
	#endif 
	
	// save to global variables
	prefd = fd_comp; 
	preHLSI = hlsi;

	
	//seek threshod judgement
	if(rssi>=170 && snr<=42 && fd_abs<=10 && fdstate)  
	{
		if((Frequency==10400||Frequency==9600||Frequency==9100)&&st==0)
		{
			return 0;
		}
			
			
		#if 0
        kal_prompt_trace(MOD_MM, "find radio is %d,%d,%d,%d \n", Frequency,rssi,snr,fd_abs);
		#endif
		
		return 1;
	}
	else
	{
		return 0;
	}
		
}




void  FMDrv_PowerOnReset(void)
{

   SerialCommCryClkOn(); //32k clock on
   SerialCommInit();     // I2C initial
   CS1100_Delay_ms(10);

   CS1100ControlData[0] &= 0x7f; //power up
   CS1100_I2C_WriteCS1100Reg(CS1100ControlData,26);	
   CS1100_Delay_ms(100); // delay 100ms, for 32k crystal, waiting for 1s to oscillate  
}
    
void  FMDrv_PowerOffProc(void)
{
	CS1100ControlData[0] |= 0x20;  // mute on
	CS1100_I2C_WriteCS1100Reg(CS1100ControlData,1);	
	
	CS1100ControlData[0] |= 0x80;  // power down
	CS1100_I2C_WriteCS1100Reg(CS1100ControlData,1);	

	SerialCommCryClkOff(); // 32k clock off
}

void FMDrv_ChipInit()
{

   SerialCommCryClkOn(); // 32k clock on

   SerialCommInit(); // I2C initial
 

   CS1100_FMInit();
   
   //FMDrv_PowerOffProc();

}
      
void  FMDrv_Mute(uint8 mute)
{
   if (mute == 0) 
   {
     CS1100ControlData[0] &= 0xdf;// mute off, audio output
    } 
   else 
   {
     CS1100ControlData[0] |= 0x20; // mute on
   }
   
   CS1100_I2C_WriteCS1100Reg(CS1100ControlData,1);
}
void  FMDrv_SetFreq( int16 curf )
{
	CS1100_FMTune(curf*10);
}

uint8 FMDrv_ValidStop(int16 freq, int8 signalvl, bool is_step_up)  //自动搜索时,作为判定条件,再从中选择信号最强的9个台
{
    uint8 ret =0;

   	CS1100ControlData[0] |= 0x20; // mute on
   	CS1100_I2C_WriteCS1100Reg(CS1100ControlData,1);

    ret =CS1100_FMSeek_Software(is_step_up,freq*10);

 	return ret;
}
uint8 FMDrv_GetSigLvl( int16 curf )  //当满足rssi 的条件时,将信号记录,再选最强的9个频点
{
     
 	unsigned int rssi,level;
    kal_uint8 Temp[6];

	CS1100_I2C_ReadCS1100Reg(Temp,6);
	rssi=Temp[1];
	level = rssi/20;

	return level;
}

  
bool  FMDrv_IsChipValid(void)
{

   static bool Fm_chip_exist = false;
   static bool Fm_chip_checked = false;

   if(Fm_chip_checked)
   {
   	return	Fm_chip_exist;
   }
   Fm_chip_checked = true;
   
  
   SerialCommCryClkOn();
   SerialCommInit();
   CS1100_Delay_ms(10);;//add by yang guangfu
   Fm_chip_exist = CS1100_FMInit();

	//FMDrv_PowerOffProc();
  
   return Fm_chip_exist;
}

void  FMDrv_SetVolumeLevel(uint8 level)   /*一般不调用,即不用芯片来调节音量。*/
{
/*
	unsigned int temp;
	if(uint8 > 0x0f)
	{
		 uint8 = 0x0f;			
	}
			
	
	temp = uint8<<2;
	temp &= 0x3c; //0x3c=00111100
	CS1100ControlData[2] |= temp;
	CS1100_I2C_WriteCS1100Reg(CS1100ControlData,3);
*/
}



#endif











⌨️ 快捷键说明

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