概述
modem-rf代码调用分析,及调试
原创 2015年07月30日 15:20:04
/*****************************************************************
1 先分析类的继承关系
2 rf卡类的分析,及构造函数过程
3 软件改动文件,及其调用过程
4 硬件端口PORT的选定方法
******************************************************************/
/*1 以下是程序中用到的类*/
最基类rfa -----作用RFC Common base class
[cpp] view plain copy
- 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
[cpp] view plain copy
- 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_procrfc_jolokiatargetmdm9609srcRfc_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_procrfdevice_qfe2520apiQfe2520_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结构体函数集合,
[cpp] view plain copy
- <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_procrfc_jolokiarf_cardrfc_wtr4905_chile_srlte_v2ltesrcRfc_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()
[cpp] view plain copy
- <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功率放大器配置数据在哪里使用呢。调用过程如下
[cpp] view plain copy
- 在打开或者关闭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_procrfc_jolokiaapiRfc_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_procrfc_jolokiatargetmsm8909srcRfc_msm_signal_info_ag.c的rfc_msm8909_signal_info[]中74管脚用两个功能
解决办法:
自己使用的gpio是在modem_procrfc_jolokiarf_cardrfc_wtr4905_omcommonsrcRfc_wtr4905_om_cmn_ag.cpp的rfc_wtr4905_om_sig_info[]中定义的,在这个数组中一个管脚不应该有服用,删掉不用的那个即可解决问题
最后
以上就是爱听歌香菇为你收集整理的modem-rf代码调用分析,及调试的全部内容,希望文章能够帮你解决modem-rf代码调用分析,及调试所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复