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

📄 si47xx_tx.c

📁 Si471x系列FM发射模块调试的参考程序
💻 C
字号:
/**************************************

Si47XX TX part

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

#include "Si47xx_common.h"

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

Si47XX_Power_Up()

***************************************/
T_ERROR_OP Si47XX_Power_Up(T_POWER_UP_TYPE power_up_type)
{
	unsigned short loop_counter = 0;
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_power_up[] = {0x01,0x41,0x05};

	switch(power_up_type)
	{
		case FM_RECEIVER:
		{
			Si47XX_power_up[1] = 0x40;
			Si47XX_power_up[2] = 0x05;  //note! for Si4730(AN385rev0.2/0.3), it's 0x05(from 0.C to 1.0)
																	//note! for Si4704/5(AN326rev0.2):
																	//0x05:analog audio
																	//0xb0:digital audio(Si4705 only with xoscen=0)
																	//0xb5:both (Si4705 only with xoscen=0)			
			break;
		}
    case FM_TRNSMITTER:
    {
    	Si47XX_power_up[1] = 0x42;
    	Si47XX_power_up[2] = 0x50;	//0x0f for digital audio input
    	break;
    }
    case AM_RECEIVER:
    {
    	Si47XX_power_up[1] = 0x41;
    	Si47XX_power_up[2] = 0x05;
    	break;
    }
    case WB_RECEIVER:
    {
    	Si47XX_power_up[1] = 0x43;
    	Si47XX_power_up[2] = 0x05;
    	break;
    }
  }
    	
	ResetSi47XX_2w();

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

	DELAY(POWER_SETTLING);	//if use internal crystal, need wait 500ms, Si47XX_power_up[1] = 0x(5x)
	
	//wait CTS = 1
	do
	{	
		error_ind = OperationSi47XX_2w(READ, &(Si47XX_reg_data[0]), 1);
		if(error_ind)
			return I2C_ERROR;	
		loop_counter++;
	}
	while(((Si47XX_reg_data[0]) != 0x80) && (loop_counter < 0xff));  //loop_counter limit should guarantee at least 300us
	
	if(loop_counter >= 0xff)
		return LOOP_EXP_ERROR;
		
	return OK;
}

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

Si47XX_Get_Rev(): read rev info: you should read out: 

{0x80,0x14,0x31,0x42,0x00,0x00,0x31,0x42,0x41} for Si4720/1B firmware, Chip rev = A(0x41).

note! only can read it correctly after power up!

***************************************/
T_ERROR_OP Si47XX_Get_Rev(unsigned char *pREV_data, unsigned char numBytes)
{
	unsigned short loop_counter = 0;
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_get_rev[] = {0x10,0x00};	

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

	//wait CTS = 1
	do
	{	
		error_ind = OperationSi47XX_2w(READ, &(Si47XX_reg_data[0]), 1);
		if(error_ind)
			return I2C_ERROR;	
		loop_counter++;
	}
	while(((Si47XX_reg_data[0]) != 0x80) && (loop_counter < 0xff));  //loop_counter limit should guarantee at least 300us
	
	if(loop_counter >= 0xff)
		return LOOP_EXP_ERROR;

	//read rev info: you should read out: {0x80,0x14,0x31,0x42,0x00,0x00,0x31,0x42,0x41} for 1B firmware
	if(numBytes > 9)
		numBytes = 9;
		
	error_ind = OperationSi47XX_2w(READ, pREV_data, numBytes);	
	if(error_ind)
		return I2C_ERROR;
		
	return OK;	

}

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

Si47XX_Set_Property_RCLK_PRESCALE()

Range:1~1023

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

T_ERROR_OP Si47XX_Set_Property_RCLK_PRESCALE(void)
{
	unsigned short loop_counter = 0;
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_set_property[] = {0x12,0x00,0x02,0x02,0x01,0x90};	//0x190=400(1~1023), 13MHz(RCLK)/400=32500Hz

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

	//wait CTS = 1
	do
	{	
		error_ind = OperationSi47XX_2w(READ, &(Si47XX_reg_data[0]), 1);
		if(error_ind)
			return I2C_ERROR;	
		loop_counter++;
	}
	while(((Si47XX_reg_data[0]) != 0x80) && (loop_counter < 0xff));  //loop_counter limit should guarantee at least 300us
	
	if(loop_counter >= 0xff)
		return LOOP_EXP_ERROR;	

	return OK;

}

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

Si47XX_Set_Property_REFCLK_FREQ()

Range:(31130~34406)!

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

T_ERROR_OP Si47XX_Set_Property_REFCLK_FREQ(void)
{
	unsigned short loop_counter = 0;
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_set_property[] = {0x12,0x00,0x02,0x01,0x7E,0xF4};	//0x7EF4=32500Hz(31130~34406)

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

	//wait CTS = 1
	do
	{	
		error_ind = OperationSi47XX_2w(READ, &(Si47XX_reg_data[0]), 1);
		if(error_ind)
			return I2C_ERROR;	
		loop_counter++;
	}
	while(((Si47XX_reg_data[0]) != 0x80) && (loop_counter < 0xff));  //loop_counter limit should guarantee at least 300us	
	
	if(loop_counter >= 0xff)
		return LOOP_EXP_ERROR;	

	return OK;

}

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

Si47XX_Set_Property_INPUT_LEVEL()

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

T_ERROR_OP Si47XX_Set_Property_INPUT_LEVEL(void)
{
	unsigned short loop_counter = 0;
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_set_property[] = {0x12,0x00,0x21,0x04,0x32,0x7C};  //max:0x27C = 636mVpk, 0x3:max=636mVpk,60kR	
																																					//even for 1Vpk line level, still should set line level to 0x27C(636mVpk)!

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

	//wait CTS = 1
	do
	{	
		error_ind = OperationSi47XX_2w(READ, &(Si47XX_reg_data[0]), 1);
		if(error_ind)
			return I2C_ERROR;	
		loop_counter++;
	}
	while(((Si47XX_reg_data[0]) != 0x80) && (loop_counter < 0xff));  //loop_counter limit should guarantee at least 300us	
	
	if(loop_counter >= 0xff)
		return LOOP_EXP_ERROR;	

	return OK;

}


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

Si47XX_Set_Property_TX_PREEMPHASIS()

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

T_ERROR_OP Si47XX_Set_Property_TX_PREEMPHASIS(void)
{
	unsigned short loop_counter = 0;
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_set_property[] = {0x12,0x00,0x21,0x06,0x00,0x01};	//tx preemphasis is 50us

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

	//wait CTS = 1
	do
	{	
		error_ind = OperationSi47XX_2w(READ, &(Si47XX_reg_data[0]), 1);
		if(error_ind)
			return I2C_ERROR;	
		loop_counter++;
	}
	while(((Si47XX_reg_data[0]) != 0x80) && (loop_counter < 0xff));  //loop_counter limit should guarantee at least 300us
	
	if(loop_counter >= 0xff)
		return LOOP_EXP_ERROR;	

	return OK;

}

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

Si47XX_Set_Property_TX_ACOMP_ENABLE()

Gain: default=15, max=20dB

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

T_ERROR_OP Si47XX_Set_Property_TX_ACOMP_ENABLE(void)
{
	unsigned short loop_counter = 0;
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_set_property[] = {0x12,0x00,0x22,0x00,0x00,0x03};	//enable audio limiter and ACEN(Audio dynamic control enable)

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

	//wait CTS = 1
	do
	{	
		error_ind = OperationSi47XX_2w(READ, &(Si47XX_reg_data[0]), 1);
		if(error_ind)
			return I2C_ERROR;	
		loop_counter++;
	}
	while(((Si47XX_reg_data[0]) != 0x80) && (loop_counter < 0xff));  //loop_counter limit should guarantee at least 300us
	
	if(loop_counter >= 0xff)
		return LOOP_EXP_ERROR;	

	return OK;

}

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

Si47XX_Set_Property_TX_Deviation()

default: TX_Audio_Deviation: 68.25KHz
				 TX_Pilot_Deviation: 6.75KHz
				 TX_RDS_Deviation:   2KHz
				 Total:							 75KHz	
***************************************/


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

Si47XX_Tune_Power()

88~115 dBuV

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

static T_ERROR_OP Si47XX_Tune_Power(unsigned short tune_power)
{
	unsigned short loop_counter = 0;
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_tune_power[] = {0x31,0x00,0x00,0x73,0x00};  //0x73=115=115dBuV for new firmwre
	//unsigned char Si47XX_tune_power[] = {0x31,0x00,0x01,0xCC,0x00};  //0x1CC/4=115=115dBuV for alpha1 firmware	

        Si47XX_tune_power[2] = (tune_power&0xff00) >> 8; 
        Si47XX_tune_power[3] = (tune_power&0x00ff);
        
	//send CMD
 	error_ind = OperationSi47XX_2w(WRITE, &(Si47XX_tune_power[0]), 5);
	if(error_ind)
		return I2C_ERROR;

	//wait CTS = 1
	do
	{	
		error_ind = OperationSi47XX_2w(READ, &(Si47XX_reg_data[0]), 1);
		if(error_ind)
			return I2C_ERROR;	
		loop_counter++;
	}
	while(((Si47XX_reg_data[0]) != 0x80) && (loop_counter < 0xff));  //loop_counter limit should guarantee at least 300us	
	
	if(loop_counter >= 0xff)
		return LOOP_EXP_ERROR;	

	return OK;

}

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

Si47XX_Tune_Freq()

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

static T_ERROR_OP Si47XX_Tune_Freq(unsigned short tune_freq)
{
	unsigned short loop_counter = 0;
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_tune_freq[] = {0x30,0x00,0x27,0x10};	//0x2710=10000=100.00MHz	
	
	Si47XX_tune_freq[2] = (tune_freq&0xff00) >> 8; 
        Si47XX_tune_freq[3] = (tune_freq&0x00ff);

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

	//wait CTS = 1
	do
	{	
		error_ind = OperationSi47XX_2w(READ, &(Si47XX_reg_data[0]), 1);
		if(error_ind)
			return I2C_ERROR;	
		loop_counter++;
	}
	while(((Si47XX_reg_data[0]) != 0x80) && (loop_counter < 0xff));  //loop_counter limit should guarantee at least 300us
	
	if(loop_counter >= 0xff)
		return LOOP_EXP_ERROR;	

	return OK;

}

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

Si47XX_Wait_STC(): wait STC = 1 (then clear it-removed)

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

T_ERROR_OP Si47XX_Wait_STC(void)
{
	unsigned short loop_counter = 0, loop_counter_1 = 0;
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_get_int_status[] = {0x14};	

	do
	{	
		//send CMD
 	  error_ind = OperationSi47XX_2w(WRITE, &(Si47XX_get_int_status[0]), 1);
	  if(error_ind)
		  return I2C_ERROR;

	  /* wait CTS = 1 and then wait STCINT = 1 */
	  do
	  {	
		  error_ind = OperationSi47XX_2w(READ, &(Si47XX_reg_data[0]), 1);
		  if(error_ind)
			  return I2C_ERROR;	
		  loop_counter_1++;
	  }
	  while(((Si47XX_reg_data[0]&0x80) == 0) && (loop_counter_1 < 0xff));  //loop_counter limit should guarantee at least 300us
	
	  if(loop_counter_1 >= 0xff)
		  return LOOP_EXP_ERROR;
		  
		loop_counter_1 = 0;
	  /* wait CTS end */
	  
	  error_ind = OperationSi47XX_2w(READ, &(Si47XX_reg_data[0]), 1);
	  if(error_ind)
		  return I2C_ERROR;	
	  loop_counter++;
	}
	while(((Si47XX_reg_data[0]&0x01) == 0) && (loop_counter < 0xffff));  //loop_counter(0xffff) limit should guarantee at least: for FM,worst case = 60ms*((108-87.5)/0.1+1)= 12s to wait STC = 1
																																			 //																										   for AM,worst case = 80ms*((1710-520)/9+1)= 11s to wait STC = 1
	if(loop_counter == 0xffff)
		return LOOP_EXP_ERROR;	

	return OK;

}

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

Si47XX_Power_Down()

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

T_ERROR_OP Si47XX_Power_Down(void)
{
	unsigned short loop_counter = 0;
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_power_down[] = {0x11};	

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

	//wait CTS = 1
	do
	{	
		error_ind = OperationSi47XX_2w(READ, &(Si47XX_reg_data[0]), 1);
		if(error_ind)
			return I2C_ERROR;	
		loop_counter++;
	}
	while(((Si47XX_reg_data[0]) != 0x80) && (loop_counter < 0xff));  //loop_counter limit should guarantee at least 300us
	
	if(loop_counter >= 0xff)
		return LOOP_EXP_ERROR;	

	return OK;

}


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

Si47XX_Set_TX_Power()

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

T_ERROR_OP Si47XX_Set_TX_Power(unsigned short tune_power)
{
	if(Si47XX_Tune_Power(tune_power) != OK) return ERROR;
	if(Si47XX_Wait_STC() != OK) return ERROR;
	return OK;
}

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

Si47XX_Set_TX_Frequency()

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

T_ERROR_OP Si47XX_Set_TX_Frequency(unsigned short tune_freq)
{
	if(Si47XX_Tune_Freq(tune_freq) != OK) return ERROR;
	if(Si47XX_Wait_STC() != OK) return ERROR;	
	return OK;
}

⌨️ 快捷键说明

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