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

📄 si4702_rx_fm.c

📁 silabs si4700/02 driver firemware 参考程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/**************************************

Si47XX FM RX part

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

#include "Si4702_common.h"

extern void RDS_data_process(unsigned char *group_data);  //group_data length is 8 bytes

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

Si4702_Power_Up()

by following setting, channel space = 100

SEEKTH: 0x0c
SKSNR: 0x04
SKCNT: 0x08

after initialization please make sure(FW/B15):
0x00: 0x1242
0x01: 0x080F/0x0A0F
0x07: 0x3C04/0xBC04(external XO)
0x08: 0x0008/0x0006
0x09: 0x0001
revC19:
0x07: 0x3C04/0xBC04(external XO)
0x08: 0x0002
0x09: 0x0000

· For the Si4702-B16: Register 01h = 0800h before powerup, 0850h after powerup.
· For the SI4703-B16: Register 01h = 0800h before powerup, 0A50h after powerup.
· For the SI4702-C19: Register 01h = 1000h before powerup, 1053h after powerup.
· For the Si4703-C19: Register 01h = 1200h before powerup, 1253h after powerup.

***************************************/
T_ERROR_OP Si4702_Power_Up(void)
{
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_power_up[] = {0x40,0x01,0x00,0x00,0x90,0x04,0x0c,0x1f,0x00,0x48};
  	
	ResetSi47XX_2w();

	//send CMD
	error_ind = OperationSi47XX_2w(WRITE, &(Si47XX_power_up[0]), 10);
	if(error_ind)
		return I2C_ERROR;

	DELAY(POWER_SETTLING);	
		
	return OK;
}

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

Si4702_Power_Up_Internal_Crystal()

by following setting, channel space = 100

SEEKTH: 0x0c
SKSNR: 0x04
SKCNT: 0x08

***************************************/
T_ERROR_OP Si4702_Power_Up_Internal_Crystal(void)
{
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_XO_enable[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81};
	unsigned char Si47XX_power_up[] = {0x40,0x01,0x00,0x00,0x90,0x04,0x0c,0x1f,0x00,0x48};
  	
	ResetSi47XX_2w();
	
	error_ind = OperationSi47XX_2w(WRITE, &(Si47XX_XO_enable[0]), 11);
	if(error_ind)
		return I2C_ERROR;

	DELAY(XO_SETTLING);	

	//send CMD
	error_ind = OperationSi47XX_2w(WRITE, &(Si47XX_power_up[0]), 10);
	if(error_ind)
		return I2C_ERROR;

	DELAY(POWER_SETTLING);	
		
	return OK;
}
/**************************************

Si4702_Power_Down()

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

T_ERROR_OP Si4702_Power_Down(void)
{
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_power_down[] = {0x00,0x41};	
	unsigned char Si47XX_disable_RDS[] = {0x40,0x01,0x00,0x00,0x00};
		
	/*following RDS disable is just for Si4703 revC19 errata solution 2: disable RDS before disable the tuner*/	
	//send CMD
 	error_ind = OperationSi47XX_2w(WRITE, &(Si47XX_disable_RDS[0]), 5);
	if(error_ind)
		return I2C_ERROR;

	//send CMD
 	error_ind = OperationSi47XX_2w(WRITE, &(Si47XX_power_down[0]), 2);
	if(error_ind)
		return I2C_ERROR;
		
	DELAY(POWER_SETTLING/4);

	return OK;

}


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

Si4702_Set_Property_FM_Volume()

FM_Volumn: 0~15

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

T_ERROR_OP Si4702_Set_Property_FM_Volume(unsigned char FM_Volumn)
{
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_set_property[] = {0x40,0x01,0x00,0x00,0x90,0x04,0x0c,0x1f};	//SNR threshold = 0x0006 = 6dB

	Si47XX_set_property[7] = (Si47XX_set_property[7] & 0xf0) | FM_Volumn;

 	error_ind = OperationSi47XX_2w(WRITE, &(Si47XX_set_property[0]), 8);
	if(error_ind)
		return I2C_ERROR;

	return OK;

}

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

Si4702_Set_Property_FM_Mute()

Enable_Mute: 0/1

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

T_ERROR_OP Si4702_Set_Property_FM_Mute(unsigned char Enable_Mute)
{
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_set_property[] = {0x40};	
  
  if(Enable_Mute)
		Si47XX_set_property[0] = 0x00;
	else
		Si47XX_set_property[0] = 0x40;
	
  error_ind = OperationSi47XX_2w(WRITE, &(Si47XX_set_property[0]), 1);
  if(error_ind)
		return I2C_ERROR;
	}
	
	return OK;

}

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

Si4702_FM_Get_RSSI()


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

T_ERROR_OP Si4702_FM_Get_RSSI(unsigned char *pRSSI)
{
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;

 	error_ind = OperationSi47XX_2w(READ, &(Si47XX_reg_data[0]), 2);
	if(error_ind)
		return I2C_ERROR;
		
	*pRSSI = Si47XX_reg_data[1];

	return OK;

}

/**************************************
Si4702_FM_Tune_Freq()

channel_freq: 8750~10800
channel_space: 50,100,200
***************************************/

T_ERROR_OP Si4702_FM_Tune_Freq(unsigned short channel_freq, unsigned char channel_space)
{
	unsigned short freq_reg_data, loop_counter = 0;
	unsigned char si4700_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char si4700_channel_start_tune[] = {0x40,0x01,0x80,0xCA};	//107.7MHz
	unsigned char si4700_channel_stop_tune[] = {0x40,0x01,0x00};	

	//set tune bit
	freq_reg_data = (channel_freq - 8750)/(channel_space/10);
	si4700_channel_start_tune[3] = freq_reg_data & 0xff; 
	si4700_channel_start_tune[2] = (si4700_channel_start_tune[2] & 0xfc) | (freq_reg_data >> 8);
	
 	error_ind = OperationSi47XX_2w(WRITE, &(si4700_channel_start_tune[0]), 4);
	if(error_ind)
		return I2C_ERROR;

	//wait STC=1
	do
	{	
		error_ind = OperationSi47XX_2w(READ, &(si4700_reg_data[0]), 1);
		if(error_ind)
			return;	
		loop_counter++;
	}
	while(((si4700_reg_data[0]&0x40) == 0) && (loop_counter < 0xffff));		//for loop_counter, when tune, the loop time must > 60ms	
		
	
	if(loop_counter == 0xffff)
    return LOOP_EXP_ERROR;

  loop_counter = 0;

	//clear tune bit
	error_ind = OperationSi47XX_2w(WRITE, &(si4700_channel_stop_tune[0]), 3);
	if(error_ind)
		return I2C_ERROR;		

	//wait STC=0
	do
	{	
		error_ind = OperationSi47XX_2w(READ, &(si4700_reg_data[0]), 1);
		if(error_ind)
			return I2C_ERROR;	
		loop_counter++;
	}
	while(((si4700_reg_data[0]&0x40) != 0) && (loop_counter < 0xff));		
	
	if(loop_counter >= 0xff)
    return LOOP_EXP_ERROR;

	return OK;

}

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

static Si4702_FM_Seek_Start()

channel_space: 50,100,200
***************************************/

static T_ERROR_OP Si4702_FM_Seek_Start(T_SEEK_MODE seek_mode, 
																			 unsigned char channel_space, 
																			 unsigned short *pChannel_Freq, 
																			 unsigned char *SeekFail, 
																			 unsigned char *valid_channel)
{
	unsigned short freq_reg_data, loop_counter = 0;
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char si4700_channel_seek_start[] = {0x41};
	unsigned char si4700_channel_seek_stop[] = {0x40};	
	
	switch(seek_mode)
	{
		case SEEKDOWN_HALT:
		{
			si4700_channel_seek_start[0] = 0x45;
			break;
		}
    case SEEKDOWN_WRAP:
    {
    	si4700_channel_seek_start[0] = 0x41;
    	break;
    }
    case SEEKUP_HALT:
    {
    	si4700_channel_seek_start[0] = 0x47;
    	break;
    }
    case SEEKUP_WRAP:
    {
    	si4700_channel_seek_start[0] = 0x43;
    	break;
    }
  }
	//set seek bit
 	error_ind = OperationSi47XX_2w(WRITE,&(si4700_channel_seek_start[0]), 1);
	if(error_ind)
		return I2C_ERROR;

	//wait STC=1
	do
	{	
		error_ind = OperationSi47XX_2w(READ,&(si4700_reg_data[0]), 1);
		if(error_ind)
			return I2C_ERROR;	
		loop_counter++;
	}
	while(((si4700_reg_data[0]&0x40) == 0) && (loop_counter < 0xffff));	//for loop_counter, when seek, the loop time must > 12s	at the worst case	
																																			//60ms*((108-87.5)/0.1+1)= 12s
	if(loop_counter == 0xffff)
    return LOOP_EXP_ERROR;

	loop_counter = 0;

	if((si4700_reg_data[0]& 0x20) != 0)
		*SeekFail = 1;
	else
		*SeekFail = 0;
		
	//you can check AFC Rail here
	if((si4700_reg_data[0]& 0x10) != 0)
		*valid_channel = 0;
	else
		*valid_channel = 1;

	//clear seek bit

⌨️ 快捷键说明

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