手机RF驱动开发

本文详细介绍了手机RF开关驱动的设计与实现过程,包括控制逻辑、函数接口定义及其内部实现等内容。通过对SANYO ASWMF46KAAACT射频开关芯片的分析,展示了如何根据射频频段和收发状态来配置控制管脚。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前面讲的是手机 RF 的硬件开发,一旦设计定型,基本就不会在改变,而且一般芯片厂家也会提供 demo 电路共参考,硬件调试也相对比较简单,都是些经验总结。按照经验积累来做,会觉得越来越简单。但是手机 RF 的驱动程序开发,估计国内没有几个公司做过,因为它涉及的部分包括基带芯片物理层的实现,协议栈,校准机制和系统整体集成。能做到这些的只能是做基带芯片且有能力开发维护协议栈的公司,这样的公司在国内还没有几家。闲话少说了。
手机 RF 包括三个 components : Transceiver 射频收发器, PA 功率放大器和 Switch 射频开关。对应着,手机 RF 驱动也分成 3 个部分: Transceiver 驱动, PA 驱动和 Switch 驱动。由易到难的开发程度排列是: Switch 驱动, PA 驱动, Transceiver 驱动。
RF 驱动的接口是由基带芯片 PAL ( Physical Abstraction Layer , the interface between L1 and driver , which is used to manage driver )定义的,因为在逻辑上, RF 驱动是由 PAL 直接调用的, PAL 实现的就是 GSM 物理层功能,如 FCCH , SCH , BCH , TCH 等物理信道的实现等等。所以 PAL 根据自己的需要,调用 RF 驱动来实现物理信道功能。这些信道大类划分就是 RX 信道和 TX 信道,对应 RF 驱动,就是分成 TX 功能和 RX 功能,所以 RF 驱动就是用 PAL 传入的频段,信道,功率,增益等参数,正确配置内部寄存器和控制管脚,实现对应的频段,频率,功率的发射和接收。
RF 驱动开发过程可以分成 4 个步骤,如下图。每个步骤都需要测试通过,作为进行下一个步骤的充分条件。

 

这里准备从最简单的 Switch 驱动开始讲解,逐渐深入,解析 RF 驱动的实现过程。其中设计到的 PAL 的知识,校准机制等都是可以独立成章的知识,会在单独的章节中做细致的解析,让你深刻了解 GSM 底层实现机制。
6.1 RF Switch 驱动 1. 控制逻辑介绍 RF Switch 驱动其实就是一个简单的逻辑控制,需要在哪个频段,是进行 TX 还是 RX 就相应的把基带连接到 Switch 的控制管脚置到 SW 文档里要求的逻辑位置,用下图举例来说明。
如 SANYO 的 SW , ASWMF46KAAACT ,芯片管脚如下图所示。

 

图中,芯片的控制管脚是 VC1 和 VC2 这两个管脚是基带射频控制管脚连接的,一般控制 RF 的都称为 TCO ,它是由 TCU 单元来进行控制。 TCO ,就是 Time Control Output , TCU 就是 Time Control Unit 。它和普通 GPO ( General Purpose Output )的区别是,它是实时控制的,可以用精确的时间来控制什么时候输出。单位是 QB ,就是 quarter bit/symbol 。详细介绍请参考:手机 RF 开发心得总结- RF 控制管脚介绍之 TCU 篇。
VC1 和 VC2 的控制逻辑关系,可从 SW 的手册上得到,如下所示。

 

0 到 0.1V ,代表逻辑‘ 0 ’ , 2.4 到 3V 代表逻辑‘ 1 ’ 。所以 SW 驱动中的控制逻辑如下:
CLR_TCO 代表管脚输出为‘ 0 ’ , SET_TCO 代表管脚输出为‘ 1 ’ 。
// GSM850 RX
g_TxRxSwTcuVal[0][0].sw1 = CLR_TCO(SW->VC1);
g_TxRxSwTcuVal[0][0].sw2 = CLR_TCO(SW->VC2);
// GSM850 TX
g_TxRxSwTcuVal[0][1].sw1 = SET_TCO(SW->VC1);
g_TxRxSwTcuVal[0][1].sw2 = CLR_TCO(SW->VC2);
// GSM900 RX
g_TxRxSwTcuVal[1][0].sw1 = CLR_TCO(SW->VC1);
g_TxRxSwTcuVal[1][0].sw2 = CLR_TCO(SW->VC2);
// GSM900 TX
g_TxRxSwTcuVal[1][1].sw1 = SET_TCO(SW->VC1);
g_TxRxSwTcuVal[1][1].sw2 = CLR_TCO(SW->VC2);
// DCS RX
g_TxRxSwTcuVal[2][0].sw1 = CLR_TCO(SW->VC1);
g_TxRxSwTcuVal[2][0].sw2 = CLR_TCO(SW->VC2);
// DCS TX
g_TxRxSwTcuVal[2][1].sw1 = CLR_TCO(SW->VC1);
g_TxRxSwTcuVal[2][1].sw2 = SET_TCO(SW->VC2);
// PCS RX
g_TxRxSwTcuVal[3][0].sw1 = CLR_TCO(SW->VC1);
g_TxRxSwTcuVal[3][0].sw2 = CLR_TCO(SW->VC2);
// PCS TX
g_TxRxSwTcuVal[3][1].sw1 = CLR_TCO(SW->VC1);
g_TxRxSwTcuVal[3][1].sw2 = SET_TCO(SW->VC2);
用一个简单的 2 维数组就可以将 SW 不同频段 TX/RX 的控制逻辑描述清楚了。下面来介绍一下 SW 相关的函数,你可以根据你开发系统物理层的需要来做适当修改。函数接口是不唯一的,但是内部实现确是根据 SW 手册上要求逻辑实现的,可以说是唯一的。
有些 SW 的控制管脚可能是 3 个,没有关系,一样可以用一个结构体数组将控制逻辑的真值表表达出来。
2. RF SW API 介绍 一般射频驱动根据作用域,分成异步功能函数和同步功能函数两种。可以这样理解:异步功能函数就是初始化, sleep/wakeup 等逻辑控制,只是根据当前手机自身状态来使用。如手机上电初始化时,需要初始化射频器件;待机操作时,需要暂时关闭射频器件等,不需要根据 GSM 网络当前状态控制射频的函数。同步功能函数就是需要根据 GSM 网络当前状态控制射频处于接收或者发送状态的函数。如:当初始化完毕时,需要搜索 GSM 网络,这时候就需要打开射频 RX 功能,搜索 FCCH , SCH , BCH ,和基站进行同步,这些都是以 frame 形式控制的,需要根据接收并判决的网络信息,找到和网络同步的时间点,并以这个时间点为参考,进行随后的同步控制。
在下面的函数中,以 Asynchronous 代表异步功能函数, Synchronous 代表同步功能函数。
先介绍一下涉及的结构定义:
//----------------------------------------------------------------------
typedef struct
{
UINT8 SW1;
UINT8 SW2;
UINT8 SW3;
}SW_CONFIG_T;
SW 连接到基带的控制管脚,最多就 3 个。
typedef enum {
RFD_DIR_RX, ///< Rx Window
RFD_DIR_TX, ///< Tx Window
RFD_DIR_RX_DOWN, ///< End of Rx Window
RFD_DIR_TX_DOWN, ///< End of Tx Window
RFD_DIR_QTY
} RFD_RFDIR_T;
typedef enum {
GSM_BAND_GSM850 = 0,
GSM_BAND_GSM900 = 1,
GSM_BAND_DCS1800 = 2,
GSM_BAND_PCS1900 = 3,
GSM_BAND_QTY
} GSM_RFBAND_T;
//----------------------------------------------------------------------
void rfd_SwOpen(CONST SW_CONFIG_T* swConfig); // Function : rfd_SwOpen
//----------------------------------------------------------------------
// Description:
/// Asynchronous./n
/// 手机 PAL 初始化时调用,根据原理图中对 SW 的控制管脚情况,初始化上面所说的控制逻辑真值表。对应函数为 rfd_SwClose 。
/// It must perform any initialization/setup needed for the Switch to be functional.
//==================================================================
void rfd_SwClose(void); // Function : rfd_SwClose
//----------------------------------------------------------------------
// Description:
/// Asynchronous./n
/// This function is called before switching off the Switch.
/// To re-enable the Switch a call to #rfd_SwOpen will be issued.
//==================================================================
void rfd_SwWakeUp(void); // Function : rfd_SwWakeUp
//----------------------------------------------------------------------
// Description:
/// Asynchronous./n
/// This function is called when going out of Low-Power mode
/// (see #rfd_SwSleep). /n
/// It must bring back the Switch in its Idle state.
//==================================================================
void rfd_SwSleep(RFD_LP_MODE_T lp_mode); // Function : rfd_SwSleep
//----------------------------------------------------------------------
// Description:
/// Asynchronous./n
/// This function is called before going to LowPower mode.
/// The Switch must go in a the Low-power state correponding to the
/// asked mode (if applicable). /n
///
///@param lp_mode : targeted Low Power mode
//==================================================================
void rfd_SwSetPosition (RFD_RFDIR_T direction, GSM_RFBAND_T band, INT16 date); // Function : rfd_SwSetPosition
//----------------------------------------------------------------------
// Description:
/// Synchronous./n
/// 根据网络当前状态设置 SW 为正确的开关状态。
/// and Band parameters.
///
///@param direction : Rx / Tx selection ( RX , TX )
///@param band : band selection ( GSM850 , GSM900 , DCS , PCS )
///@param date : start time (in Qb) of the window, corresponds to
/// the beginning of the first sent (for Tx) or received (for
/// Rx) bit of the usefull part of the burst.
/// This time doesn't include any offset specific to the Rf
/// Switch.
//==================================================================
rfd_SwSetPosition 解析 VOID rfd_SwSetPosition (RFD_RFDIR_T direction, GSM_RFBAND_T band, INT16 date)
{
因为是同步控制,所以 date 代表网络要求打开 SW 的时间( SW 只是被动器件,具体什么时候打开,由基带物理层根据 GSM 物理层协议控制。) SW_TIME_TX_SWITCH_UP 这类宏定义的时间是相对时间,参考时间点是网络要求打开 SW 的时间。这个宏定义时间一般都是负数,因为任何控制管脚的有效输出都需要一个建立时间,所以输出宏定义就是管脚到有效输出的建立时间。而且这个时间还需要实际调试时进行适当修改。
如先期在 8960 上调试 TX 时,如发现 PVT 的轮廓没有在框内的合适位置,则需要调整 TX_UP 或者 TX_DOWN 的时间来调整。
if (direction == RFD_DIR_TX)
{
date += SW_TIME_TX_SWITCH_UP;
}
else if (direction == RFD_DIR_TX_DOWN)
{
// Switch to RX to provide isolation (needed for ETSI specs)
date += SW_TIME_TX_SWITCH_DN;
direction = RFD_DIR_RX; // 如果影响 GPRS ,则不需要改变 direction ,保持 TX
}
else if (direction == RFD_DIR_RX_DOWN)
{
// Nothing to do for Rx Down
return;
}
else // RFD_DIR_RX
{
date += SW_TIME_RX_SWITCH_UP;
}
这里开始真正的控制输出,首先判断上次 SW 的控制管脚状态,如果和当前控制相同,则不需要变换管脚输入状态。
// Optimized way : program only switch changes
if (g_SwTcuCfg.sw1 != g_TxRxSwTcuVal[band][direction].sw1)
{
g_SwTcuCfg.sw1 = g_TxRxSwTcuVal[band][direction].sw1;
TcuSetEvent (g_SwTcuCfg.sw1, date);
}
if (g_SwTcuCfg.sw2 != g_TxRxSwTcuVal[band][direction].sw2)
{
g_SwTcuCfg.sw2 = g_TxRxSwTcuVal[band][direction].sw2;
TcuSetEvent (g_SwTcuCfg.sw2, date);
}
}

以上就是 SW 基本的控制逻辑,其实还是需要仔细阅读 SW 手册,里面包含很多信息。如 : TX /RX Insertion Loss (需要测试时做补偿) 和 TX Isolation 最重要。 ( TX Isolation :前端隔离度,防止 TX 辐射到 RX ,影响 RX 性能,这就是问什么 TX_DOWN 后,需要把 DIR 置为 RX 方式,就是为了防止 SW 的 TX 辐射到 RX 。)需要注意的是,做 GPRS 时,因为需要多个连续的 TX SLOT ,所以 TX_DOWN 后,如果把 DIR 置为 RX ,会影响 GPRS 的速率。这时,如果隔离度足够,不影响 RX performance ,则 TX_DOWN 后,不需要设成 RX 。

 

做射频驱动,其实最重要的还是多做试验,使用示波器抓取控制时序,结合驱动及器件文档的细节规格,使用 8960 和频谱分析仪来优化性能,这才是开发驱动的本意。 
 

本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/zz2006/archive/2010/09/28/5910966.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值