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

来源:互联网 发布:淘宝金蛋 编辑:程序博客网 时间:2024/06/06 07:08
/*****************************************************************
1 先分析类的继承关系
2 rf卡类的分析,及构造函数过程
3 软件改动文件,及其调用过程
4 硬件端口PORT的选定方法

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


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

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

class rfdevice_rxtx_common_class:public rfdevice_classclass rfdevice_rxtx_common_adapter : public rfdevice_rxtx_common_classclass rfdevice_rxtx_common_class:public rfdevice_class //rfdevice_rxtx_common_class添加了一些对设备的操作:如设置路径,上电,改变state,reg dumpclass rfdevice_class: public rfa    //rfdevice_class添加了一些设备的基本信息,如厂家id,设备id,设备类型,实例号等操作信息class rfdevice_trx_wcdma_rx_adapter:public rfdevice_trx_wcdma_rxclass 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_asmclass rfdevice_asm:public rfdevice_classclass 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 datacreate_cmn_rf_devicesphys_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 instancesswitch(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);#endifif ( (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_bandsrfc_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_objectnew 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_txagcpa_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[]中定义的,在这个数组中一个管脚不应该有服用,删掉不用的那个即可解决问题

3 0
原创粉丝点击