modem-rf代码调用分析,及调试

/*****************************************************************
1 先分析类的继承关系
2 rf卡类的分析,及构造函数过程
3 软件改动文件,及其调用过程
4 硬件端口PORT的选定方法

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


/*1 以下是程序中用到的类*/

最基类rfa -----作用RFC Common base class

	class rfdevice_rxtx_common_class:public rfdevice_class
		class rfdevice_rxtx_common_adapter : public rfdevice_rxtx_common_class	
			class rfdevice_rxtx_common_class:public rfdevice_class	 //rfdevice_rxtx_common_class添加了一些对设备的操作:如设置路径,上电,改变state,reg dump
				class rfdevice_class: public rfa    //rfdevice_class添加了一些设备的基本信息,如厂家id,设备id,设备类型,实例号等操作信息

class rfdevice_trx_wcdma_rx_adapter:public rfdevice_trx_wcdma_rx
	class rfdevice_trx_wcdma_rx:public rfdevice_class      //rfdevice_trx_wcdma_rx主要增加了一些virtual函数接口,如,setband disable entermode setport,不过真正的操作函数还得由子类自己实现
		class rfdevice_class: public rfa         //rfa代表什么设备


class rfc_wtr4905_chile_srlte_v2_lte_ag:public rfc_lte_data   //子类中有相关函数,所以会调用子类中定义的函数
	class rfc_lte_data : public rfa            //rfc_lte_data类中定义了一些虚函数,如果子类同名,则覆盖
	
class rfdevice_asm_common:public rfdevice_asm
	class rfdevice_asm:public rfdevice_class
		class rfdevice_class: public rfa

/*2 以下是程序rf卡的代码初始化过程*/

//构造函数,  Create rf device objects based on the rf-card specific device configuration info

rfc_intf(rf_hw_type rfhw, system_clock_enum sysclk) :
	// Initializes the RFC common module,主要初始化设置RF_GRFC/GRFC/GPIO initialization;
	rfc_common_init(rfc_info_table, rfc_signal_num);
		rfc_msm_signals_num = rfc_msm_sig_info_table_get(&	rfc_msm_signal_info_table);相应的平台src中定义次函数,比如:\modem_proc\rfc_jolokia\target\mdm9609\src\Rfc_msm_signal_info_ag.c
															相关rf管脚的定义信息
		for (i = 0; i < rfc_signals_num ; i++)
			//设置相关的硬件管脚
			rfc_common_set_grfc(rc_msm_signal_info_table[msm_signal].grfc_num, rfc_signal_info_table[i].init_state);  //来自lib
	
	// create all the rf device objects based on the device configuration data
	create_cmn_rf_devices
		phys_devices_array = modem_mem_alloc(sizeof(rfc_physical_device_struct_type)*phys_devices_count,MODEM_MEM_CLIENT_RFA);   //分配phys设备内存
		memset(phys_devices_array, 0, phys_devices_count*sizeof(rfc_physical_device_struct_type));   //初始化内存
		/*Create the physical device,创建物理设备,以下有逻辑设备。一个逻辑设备只能对应一个物理设备,一个物理设备可以对应多个逻辑设备*/
		phys_dev = rf_device_factory_create_phys_device(&phy_devices_cfg[index]);
						return new qfe2520_physical_device(cfg, FALSE);\modem_proc\rfdevice_qfe2520\api\Qfe2520_physical_device.h中定义的结构体

		/**********************************Adding physical device objects to the physical devices array indexed by the physical device instance****************/
		/*Store the phy obj to the phy devices array,将实体跟数组相关联,方便调用,程序里会有一个物理设备的一个链表*/
		while(){
		phys_devices_array[phy_dev_instance].device_obj = phys_dev;
		phys_devices_array[phy_dev_instance].device_status = RFC_DEVICE_PRESENT;
		phys_devices_array[phy_dev_instance].phy_dev_cfg = &phy_devices_cfg[index];
		}

		/**********************************Create logical components listed in the RFC for each physical device 创建logic设备*************************************************/
		/*populate the old device config structure,取出配置信息,我们在程序里会有一个逻辑设备的一个链表,后边看是不是两者对用*/
		for(){
		device_cfg.associated_rf_device_type    = RFDEVICE_TRANSCEIVER;
		device_cfg.associated_rf_asic_id        = phy_dev_instance;
		device_cfg.rf_device_type               = logical_devices_cfg[index].rf_device_type;
		device_cfg.rf_device_id                 = logical_devices_cfg[index].rf_device_id;
		device_cfg.rf_asic_id                   = logical_devices_cfg[index].rf_asic_id;
		device_cfg.rf_device_comm_protocol      = phys_devices_array[phy_dev_instance].phy_dev_cfg->rf_device_comm_protocol;
		device_cfg.bus[0]                       = phys_devices_array[phy_dev_instance].phy_dev_cfg->bus[0];
		device_cfg.bus[1]                       = phys_devices_array[phy_dev_instance].phy_dev_cfg->bus[1];
		device_cfg.manufacturer_id              = phys_devices_array[phy_dev_instance].phy_dev_cfg->manufacturer_id;
		device_cfg.product_id                   = phys_devices_array[phy_dev_instance].phy_dev_cfg->product_id;
		device_cfg.product_rev                  = phys_devices_array[phy_dev_instance].phy_dev_cfg->product_rev;
		device_cfg.default_usid_range_start     = phys_devices_array[phy_dev_instance].phy_dev_cfg->default_usid_range_start;
		device_cfg.default_usid_range_end       = phys_devices_array[phy_dev_instance].phy_dev_cfg->default_usid_range_end;
		device_cfg.assigned_usid                = phys_devices_array[phy_dev_instance].phy_dev_cfg->assigned_usid;
		device_cfg.group_id                     = phys_devices_array[phy_dev_instance].phy_dev_cfg->group_id;
		device_cfg.init_required                = phys_devices_array[phy_dev_instance].phy_dev_cfg->init_required;
		device_cfg.associated_dac               = phys_devices_array[phy_dev_instance].phy_dev_cfg->associated_dac;
		}
		
		
		rf_device_factory_create_device	   //creating device instances
			switch(cfg->rf_device_id) 
			case WTR2605:
				rf_device_factory_create_wtr2605_device  //创建设备实例      creating WTR2605 instance
					//create WTR2605 common device    //通用属性存储
					rfdevice_rxtx_common_class* legacy_cmn_device = new wtr2605_rxtx_common_class(wtr2605_bus_info, cal_data);
					instance = new rfdevice_rxtx_common_adapter( legacy_cmn_device, cfg->rf_asic_id );
					/*! create WCDMA device*/
					#ifdef FEATURE_GSM 
					#ifdef FEATURE_TDSCDMA
					#ifdef FEATURE_WCDMA              //特性属性存储
					wtr2605_wcdma_create_device(wtr2605_common->get_instance());
					//发送设备跟接收设备实例不通,都有自己的专用函数,如接收结构里边包含rfwcdma_rxdev_func_tbl_type结构体函数集合,
<span style="white-space:pre">													</span>发送结构里边包含rfwcdma_txdev_func_tbl_type结构体函数集合
					new rfdevice_trx_wcdma_rx_adapter((rfdevice_rxtx_common_class*)instance,  RFDEVICE_TRX_PATH_0, cfg->rf_asic_id);
					new rfdevice_trx_wcdma_tx_adapter((rfdevice_rxtx_common_class*)instance,  RFDEVICE_TRX_PATH_0);
					#endif
		if ( (logical_devices_cfg[index].rf_device_id == GEN_ASM) || (logical_devices_cfg[index].rf_device_id == GEN_PA) )
		{
		dev_obj = create_gen_device_object(phys_devices_array[phy_dev_instance].device_obj,(&logical_devices_cfg[index]));  //主要来设置配置好的数据,详细调用见附录2
		}
	create_lte_rfc();
		rfc_lte_data::get_instance();
			rfc_lte_data_ptr = (rfc_lte_data *)new  rfc_wtr4905_chile_srlte_v2_lte_ag();    //为rfcard分配堆栈,
								/*\modem_proc\rfc_jolokia\rf_card\rfc_wtr4905_chile_srlte_v2\lte\src\Rfc_wtr4905_chile_srlte_v2_lte_config_ag.cpp会实现类中的成员*/

	create_gsm_rfc();      //同上
	create_tdscdma_rfc();  //同上
	create_wcdma_rfc();    //同上
		rfc_wcdma::create_instance();
			rfc_wcdma_ptr = (rfc_wcdma *)new 	rfc_wcdma(); 
												构造函数rfc_wcdma::	rfc_wcdma()
<pre name="code" class="cpp">附录1
/*3 软件改动文件,及其调用关系*/
分支调用分析    initializes the rfdevices with the rfc dependent data.用我们设定的数据初始化所有的射频芯片
init_rfdevices_for_all_bands
	rfc_wcdma_data *rfc_data = rfc_wcdma_data::get_instance(); 
								rfc_wtr4905_amx_wcdma_ag:get_instance     //因为class rfc_wtr4905_amx_wcdma_ag:public rfc_wcdma_data父子类关系,所以会调用到这里
															//我们对band的改动(增删改)的修改就会修改到此函数
	rfc_data->devices_cfg_data_get(&cfg, &device_info_ptr); 
			rfc_wtr4905_amx_wcdma_ag::devices_cfg_data_get(); //原理同上,我们对band的改动(增删改)的修改就会修改到此函数
						会得到以下数组rfc_device_info_type rf_card_wtr4905_amx_tx0_wcdma_b2_device_info
						
	以下过程,不同的轮询条件会多次调用{->
	//if ( ( cfg->rx_tx == RFC_CONFIG_TX ) && ( cfg->logical_device == RFM_DEVICE_0 ) && ( cfg->alternate_path == 0 /*Warning: not specified*/ ) && ( cfg->band == (int)RFCOM_BAND_IMT ) && ( cfg->req == RFC_REQ_DEFAULT_GET_DATA ) && !ret_val )
	cfg.alternate_path = 0;              //进行一次轮询之前,先设定轮询条件,轮询过程中会进行相应的判定(如上一行)
	cfg.logical_device = RFM_DEVICE_0;
	cfg.rx_tx = RFC_CONFIG_RX;
	cfg.req = RFC_REQ_DEFAULT_GET_DATA;		 
	for(){
		rfc_data->devices_cfg_data_get(&cfg, &device_info_ptr);	
		init_rf_devices(&cfg, device_info_ptr);    //进行一次轮询 初始化rf


		
			  /* Attempt to map all devices for this configuration. */
				  while (i < device_info_ptr->num_devices)
					phy_path = (rfdevice_trx_phy_path_enum_type) device_info_ptr->rf_asic_info[i].phy_path_num;物理设备的总数这里会用到,所以应该设置
					dev_type = device_info_ptr->rf_asic_info[i].device_type;
					switch(dev_type)
								case RFDEVICE_TRANSCEIVER:
									if (RFC_CONFIG_RX == cfg->rx_tx)
									else if (RFC_CONFIG_TX == cfg->rx_tx) /* tx device data */
										/* Confirm we have a valid Primary or Secondary receive path */
										<span style="white-space:pre">	</span>if (cfg->logical_device >= RFM_DEVICE_0 && cfg->logical_device <= RFM_DEVICE_3)
												rfdevice_wcdma_rx_set_band_data( cfg->logical_device,      //找不到函数定义,应该在高通的lib文件中有
																			 rx_dev_obj,
																			(rfcom_wcdma_band_type)cfg->band,
																			    device_info_ptr->rf_asic_info[i].data,
																					RFC_ASIC_INFO_DATA_SIZE);
								case RFDEVICE_PA: 
									if(cfg->rx_tx == RFC_CONFIG_TX) 
										  ((rfdevice_pa *)cmn_dev_obj)->set_band_map
															 
								case RFDEVICE_ASM:
								if (cfg->rx_tx == RFC_CONFIG_RX)
									 {
									   ((rfdevice_asm *)cmn_dev_obj)->set_rx_band_map(cfg->logical_device, RFM_IMT_MODE, rf_band, ....
									 }	
									 else if (cfg->rx_tx == RFC_CONFIG_TX)
									 {
										 ((rfdevice_asm *)cmn_dev_obj)->set_tx_band_map(cfg->logical_device, RFM_IMT_MODE, rf_band, .....
									 }/* !RFC_CONFIG_TX */ 
								case RFDEVICE_PAPM:
									 ((rfdevice_papm *)cmn_dev_obj)->set_band_map(cfg->logical_device,
																   RFM_IMT_MODE, rf_band, 
																   device_info_ptr->rf_asic_info[i].data, 
																   RFC_ASIC_INFO_DATA_SIZE);
	}														   
	<-}	





/*4,硬件端口PORT的选定方法,自己总结的不知道对不对~~*/
typedef enum 
{
  WTR4905_WCDMA_DRXLGY1_BAND1_DMB1, 
**************
  WTR4905_WCDMA_DRXLGY1_BAND19_DLB3, 
  WTR4905_WCDMA_DRXLGY1_BAND8_DLB2, 
  以下步骤跟据硬件给的图来决定
  WTR4905_WCDMA_DRXLGY1_BAND8_DLB3, 
                        先决定是哪个band
  WTR4905_WCDMA_DRXLGY1_BAND11_DMB1, 
  再决定是否为主接受
  WTR4905_WCDMA_DRXLGY1_BAND11_DMB2, 
							   D代表rx1,副接收,用rx1表示   如:   rf_card_wtr4905_om_rx1_wcdma_b8_device_info
  WTR4905_WCDMA_PRXLGY1_BAND1_PMB2,                                                              b8表示BAND8
							  P代表rx0表示主接收 用rx0表示   如:   rf_card_wtr4905_om_rx0_wcdma_b8_device_info
  WTR4905_WCDMA_PRXLGY1_BAND1_PMB3, 
  WTR4905_WCDMA_PRXLGY1_BAND1_PHB1,
                                 再决定后边的数字  
  WTR4905_WCDMA_PRXLGY1_BAND1_PHB2, 
  WTR4905_WCDMA_PRXLGY1_BAND2_PMB2, 
*****************
  WTR4905_WCDMA_PRXLGY1_BAND8_PLB2, 
  WTR4905_WCDMA_PRXLGY1_BAND8_PLB3, 

  WTR4905_WCDMA_RX_BAND_INVALID, 
} wtr4905_wcdma_rx_port_data_type;

	
/*附录2*/
1.创建对象
create_gen_device_object       //上边总函数会调用到
   case GEN_PA:
     return (create_gen_pa_object( rfdevice_physical_third_party_p , logical_device_cfg ) );
				new rfdevice_pa_common(rfdevice_physical_ptr ,phy_device_cfg,logical_device_cfg); /* create the PA device */
					rfdevice_pa_data_create      //构造函数会调用到它
						rfdevice_pa_sky_77629_data_ag::get_instance();//根据id选择调用
							new rfdevice_pa_sky_77629_data_ag();
   case GEN_ASM:
     return (create_gen_asm_object( rfdevice_physical_third_party_p , logical_device_cfg ) );
				create_gen_asm_object
				new rfdevice_asm_common(rfdevice_physical_ptr,phy_device_cfg,logical_device_cfg); /* create the ASM device */ <==>会调用构造				
					rfdevice_asm_common::rfdevice_asm_common(rfdevice_physical_device *phy_dev_obj_ptr,	rfc_phy_device_info_type *phy_device_info, rfc_logical_device_info_type *logical_device_info)			
						rfdevice_asm_data_create (uint16 mfg_id, uint8 prd_id, uint8 prd_rev)
							if ( mfg_id ==  0x01A5 && prd_id == 0x41  && prd_rev == 0)
							{
							asm_data = 	rfdevice_asm_sky13455_data_ag::get_instance();
											rfdevice_asm_sky13455_data_ptr = (rfdevice_asm_data *)new rfdevice_asm_sky13455_data_ag(); //调用构造函数

													



2.配置对象	
asm开关选择配置数据应用												
config(asm_cfg_p, TRUE, script_buffer,   execution_type, script_timing);类似配置设置函数都会调用到settings_data_get,来使用到数据手册对应过来的寄存器												
		asm_data_ptr->settings_data_get(&asm_cfg, &asm_settings);								
			if (cfg->req == RFDEVICE_ASM_ON_DATA)
			{
				settings->addr = &(rfdevice_asm_sky13455_asm_on_regs[0]);            //开关的寄存器
				settings->data = &(rfdevice_asm_sky13455_asm_on_data[cfg->port][0]); //选择相应开关时寄存器中的内容
				settings->num_regs = RFDEVICE_ASM_SKY13455_ASM_ON_NUM_REGS;
				ret_val = TRUE;
			}
pa功率放大器配置数据在哪里使用呢。调用过程如下
在打开或者关闭pa的时候会调用到<span style="font-family: Arial, Helvetica, sans-serif;">set_pa_on_off,这时候会调用到我们设置的配置参数。</span>
set_pa_on_off  或config中都会调用到
	set_pa_txagc			
		pa_data_ptr->settings_data_get(&pa_params_cfg, &pa_reg_ag);			
			if ( (cfg->req == RFDEVICE_PA_ON_DATA) )
			{
				settings->addr = &(rfdevice_pa_sky_77629_51_pa_on_regs[0]);
				settings->data = &(rfdevice_pa_sky_77629_51_pa_on_data[cfg->port][0]);
				settings->num_regs = RFDEVICE_PA_SKY_77629_51_PA_ON_NUM_REGS;
				ret_val = TRUE;
			}
	

rf调试

①:先设置nv项

nv00453:Factory Testmode Phone Mode,设置为1,开机会先进入FTM模式,不至于在没配置好的情况下直接进入offline

nv06828:LTE BC Config :选定lte支持的band的位

nv01878:RF Hardware Configuration,配置为你选定的rf_hw_type       (参照:modem_proc\rfc_jolokia\api\Rfc_hwid.h)

②:配置modem可以单独重启

#sudo push busybox  /data/

#adb shell

#  ./data/busybox find ./ -name restart_level

./sys/devices/soc.0/4080000.qcom,mss/subsys2/restart_level
./sys/devices/soc.0/a21b000.qcom,pronto/subsys1/restart_level
./sys/devices/soc.0/1de0000.qcom,venus/subsys0/restart_level

#cat ./sys/devices/soc.0/4080000.qcom,mss/subsys2/restart_level

SYSTEM

echo RELATED ./sys/devices/soc.0/4080000.qcom,mss/subsys2/restart_level   //modem 可以单独重启

③:QXDM抓去log

alt+i 清楚log

send_data 75 37 03 00   //重启modem

筛选log:rffe 或 rf,一下为筛选结果




从中可以判定哪个器件没检测到,如果    rfc_prd_id ,hw_prd_id=0x0不一样,则次器件出问题(图中第三个就有问题)

QXDM的其他命令:

mode online

mode mpl

send_data 75 37 03 00

.....



关于gpio的配置

    { (int)RFC_WTR4905_OM_RF_PATH_SEL_04,   { RFC_HIGH, -10 }, {RFC_LOW, 0 }  },

配置完成后,硬件测试管脚电平没有变高???最终确定是复用了

modem_proc\rfc_jolokia\target\msm8909\src\Rfc_msm_signal_info_ag.c的rfc_msm8909_signal_info[]中74管脚用两个功能

解决办法:

自己使用的gpio是在modem_proc\rfc_jolokia\rf_card\rfc_wtr4905_om\common\src\Rfc_wtr4905_om_cmn_ag.cpp的rfc_wtr4905_om_sig_info[]中定义的,在这个数组中一个管脚不应该有服用,删掉不用的那个即可解决问题

展开阅读全文

没有更多推荐了,返回首页