AD9364软件配置

本文详细介绍了AD9364射频收发芯片的配置流程,包括初始化结构体、时钟树配置、复位机制、接口控制、状态机管理和滤波器设置等关键步骤。重点讨论了时钟源的选择、数字基带的配置以及增益控制模式。内容适用于基于STM32F407ZGT6微控制器的系统集成与开发。

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

AD9364的软件配置

(备注:本文以官方提供的源码为基础,并根据项目要求进行修改。主控为STM32F407ZGT6,编程语言为C,但是配置思路可供一般性参考。另外,由于在项目中这块芯片的部分功能我们并没有使用(比如配置较为复杂的AGC),所以没有包含相关内容,仅仅说明了我们用到的,欢迎大家进一步补充或完善相关文档)
(PS:本文主要参考1.AD9364 Datasheet 2.AD9364 manual 3.AD9364 register map )
代码链接:https://download.csdn.net/download/m0_46482248/87836374
文献链接:https://download.csdn.net/download/m0_46482248/87836683
先说明本文的写作结构,以及总体代码的结构。

本文结构:

1.说明整体的配置流程,认识到哪些函数是重要的,主体函数是哪些。
2.说明AD9364芯片内由哪些重要的部分组成,这些部分是由哪些函数配置的。

代码结构:

在工程中找到main.c文件,会发现其中有一个用于配置的结构体1,和整体的初始化函数函数1。这两者在下面有介绍,这是最外层的包装,所有的初始化都会通过这两者完成。在函数1中会将结构体1的值记录在结构体2中,结构体2中的值将会依次配置到芯片中,且配置好后结构体的值会被实时更新与芯片内部保持一致。函数2函数1中最主要的执行函数,其他部分都在做配置的准备工作,没有直接与芯片交互,所以调试时,最要检查函数2内的函数是否正常执行,配置时,直接在结构体1中找到对应项。
上述AD9364的两大结构体和两大主函数如下:
结构体1AD9361_InitParam
说明:这个结构体是我们放在主函数中,我们可以对其进行手动填值,然后对调用函数将其传入对芯片进行初始化配置。
用途:初始化
结构体2ad9361_rf_phy
说明:这个结构体是由函数进行填值的,其目的是对芯片的实时参数进行记录,也对要配置的参数进行记录,所以其内部相比于结构体1来说会复杂得多,因为其成员还有结构体:例如对要配置的参数进行存储的ad9361_phy_platform_data结构体。
用途:查看芯片当前状态,初始化后对芯片进行配置
函数1int32_t ad9361_init (struct ad9361_rf_phy **ad9361_phy, AD9361_InitParam *init_param)
说明:这个函数是初始化的主要函数,这个函数首先将结构体1的数据赋值给对应的结构体2中的ad9361_phy_platform_data,以便后续调用函数进行配置。
具体来说:这个函数传入两个参数,其中第一个参数是空的,这个函数要将AD9361_InitParam结构中的数据赋予ad9361_rf_phy,并且完成一系列初始化工作。
1、首先是将AD9361_InitParam中的参数挨个赋予ad9361_rf_phy
2、然后对设备进行reset,reset是通过调用int32_t ad9361_reset(struct ad9361_rf_phy *phy)实现的,其内部首先尝试使用GPIO口对reset引脚进行拉低,若不成功则使用配置寄存器的方式拉低。
3、检查设备型号,通过读寄存器(0x037)的方式进行。
4、将所有的时钟分配好,主要的方式是通过晶振频率以及分倍频数来计算,填入ad9361_rf_phy
5、根据phy的参数,调用int32_t ad9361_setup(struct ad9361_rf_phy *phy)启动设备

用途:输入结构体1和结构体2,对芯片进行初始化,并将芯片信息记录在结构体2中
函数2int32_t ad9361_setup(struct ad9361_rf_phy *phy)
说明:这个函数只是函数1调用的若干函数中的一个,在这里特别提出的原因是,其完成了函数1中实际对芯片配置的绝大部分工作,或者说函数1其实只是函数2的包装。下面描述的芯片配置基本上都是这个函数中的内容。
用途:实际根据结构体2配置芯片。

芯片配置总览

由于AD9364几乎是一个完整的收发链路,所以较为复杂,配置AD9364前,我们需要对AD9364有哪些东西需要配置有一个整体的认知,这样不至于在配置的过程中在各种各样的函数中迷失。我们必须了解AD9364需要配置的几大部分,他们分别是:
1、时钟树
2、增益控制
3、接口控制
4、带宽/滤波器配置
5、状态机控制
将这几部分理解并配置完成,基本就能成功运行AD9364。

芯片配置细则

AD9364的复位

AD9364有两种复位方式,硬件异步复位以及写寄存器进行复位,官方更加推荐的是硬件复位,所以一般程序开始前,要首先进行硬件复位。即拉低RESETB引脚,然后等待一段时间后再进行拉高。

AD9364的时钟树

时钟树概览

AD9364一共有3个主PLL,分别用于RX,TX和Baseband。由这三个主时钟,经过分频器层层分频给整个芯片的各个部分提供时钟,共计16个时钟。因此在时钟方面我们实际上要操作的是三个PLL和约10个分频器。
PLL部分:若对于PLL的结构有一个初步了解,我们知道其环路中有VCO和CP,所以配置PLL时需要对他们进行校准,尽管这些通常封装在函数中,但是出现问题时是需要知道是在哪里操作的。
分频器部分:分频器通常只需要向寄存器中写入分频的分子和分母即可,这些操作也是通过调用函数来实现的,输入Parent source 和 Current source,函数即可计算对应的分频系数。当我们知道其是基于分子分母来配置的时候,有一些问题也就可以解释了,即我们能设置的频率并不是一个连续的实数,不可能配置出99.99999MHz这样的频率,因为分频的精度有限。
整个时钟树的命名及关系如下:
在这里插入图片描述
中间部分我们称为基带,左边我们称为接收时钟树,右边为发射时钟树

时钟的输入

硬件部分:一个芯片通常只有一个晶振,AD9364同样如此,这三个PLL有同一个源头。这个源头可以是一个有源晶振提供(只接XTALN脚,XTALP脚悬空),或者是无源晶振与芯片内部的可编程振荡器共同提供(接XTALP和XTALN脚)。
我们采用的是使用外部时钟,即有源晶振输入,只接XTALN脚。
输入范围:5M-320M 推荐值80M,160M,320M,40M。这里我们采用40M有源晶振
软件部分:从上面的硬件描述可以看出,既然它能支持两种模式的输入,那么这大多是需要软件配置的,所以时钟的输入的软件部分主要就是选择模式。这一部分呢,是最先配置的,在int32_t ad9361_init (struct ad9361_rf_phy **ad9361_phy, AD9361_InitParam *init_param)函数中,直接对寄存器0x009进行写入, 0x009的详细情况如下:
在这里插入图片描述
配置的时候是,同时将上面的8位配入(若是用的有源晶振D4配置位1)。这是芯片复位后要进行的第一个操作:配置时钟输入,使能数字时钟,使能基带锁相环。

数字基带配置

如上面的时钟树所展示的中间部分,这里需要首先对参考进行配置,然后对接收和发射基带进行配置。
1、BB_REFCLK时钟的配置
这个是配置晶振进来后的第一个分频器,用int32_t clk_set_rate(struct ad9361_rf_phy *phy, struct refclk_scale *clk_priv, uint32_t rate)进行配置,这个按照手册一般配置为80MHz,这个是不需要自己设的,这个由ad9364.h文件中定义的MAX_BBPLL_FREF,和那个初始化AD9361_InitParam结构体的refin_fre频率共同决定。
2、BBPLL时钟链路的配置
调用int32_t ad9361_set_trx_clock_chain(struct ad9361_rf_phy *phy, uint32_t *rx_path_clks, uint32_t *tx_path_clks),配置基带的各个时钟。其中对BBPLL的配置较为复杂,需要VCO等,其他的同上面的一样,设置分频器即可。
PLL的设定主要的步骤有:
a、由于在可选的频率范围内有无数个频点,而数字器件只能通过写寄存器的方式实现频率的变化,寄存器的变化总数,所以首先计算你设定的频率最接近的能够设定的频率
b、配置环路滤波器,电荷泵
c、启动VCO校准
d、写入频率字
上述这些步骤在int32_t ad9361_bbpll_set_rate(struct refclk_scale *clk_priv, uint32_t rate, uint32_t parent_rate)中进行。
其他的都是算分频系数,配分频的寄存器。

接收本振配置,发射本振配置

与上面基带配置类似这里不再赘述,见代码直接明了。

AD9364的接口配置

这部分介绍AD9364的接口,AD9364有RF输入的接口,SPI通信接口,控制管脚,检测管脚,并行数据输出管脚,以及其他auxadc、auxdac等等,这些的配置需要选择。

RF输入口

由于AD9364有三个RF输入口A,B,C,需要选择。至于为什么有三个口,个人觉得可能是给不同频段的前端链路准备的。这些是通过init函数中的int32_t ad9361_rf_port_setup(struct ad9361_rf_phy *phy, bool is_out, uint32_t rx_inputs, uint32_t txb)配置的,主函数中的init_param结构体中的rx_rf_port_input_select设置,与值对应的是:
在这里插入图片描述

基带信号传输

这部分主要有三个配置寄存器的配置,可以配置并行口的顺序、相位等等,这些是用init函数中的static int32_t ad9361_pp_port_setup(struct ad9361_rf_phy *phy, bool restore_c3)配置的,配置的参数在pd->port_ctrl.pp_conf中,当数据出现了数据不对时需要检查这一部分
其中LVDS数据的相关传输信号如下:
1、DATA_CLK/FB_CLK
这个是差分时钟信号,其中DATA_CLK是AD9364提供给BBP的(也就是Rx通路的时钟),FB_CLK正好相反是BBP需要提供给AD9364的(也就是Tx通路的时钟)。
时钟的频率是由RF通道数,过采样程度,带宽决定的
时钟信号还可以在SPI通信期间关闭来降低功耗
2、Rx_FRAME/Tx_FRAME
帧开始的标志,上升沿表示帧开始
有两种模式,一种是burst开始的时候有一个上升沿,然后在burst期间保持不变;另一种是一个脉冲串每一帧都有一个上升沿。
3、Rx_D[5:0]/Tx_D[5:0]
差分数据接口
4、ENABLE
一个DATA_CLK的高电平开始一段burst,再一个DATA_CLK高电平结束一段burst
5、TNXRN
TDD模式中决定了传输方向,高电平发射,低电平接收。
这个信号只能在ALERT状态下转换,因为这个信号会影响本振的电源
LVDS模式下的双向端口复用模式
接收端口:Rx_D[5:0],DATA_CLK,Rx_FRAME
通过DATA_CLK以及时序图可以提取其他接口的信息,Rx_FRAME标志了一个帧的起始。
接收到的信号格式:二进制补码,因为接口一次能发6个数据,所以第一个6-bit表示MSB,第二个6-bits表示LSBs,所以最大的正值应该是0x7FF也就是(0111 1111 1111),其中第一个6-bit是0x1F也就是(01 1111),第二个6-bit是0x3F(11 1111);最小的负值是0x800(1000 0000 0000,即-0,?这里似乎有问题)。Rx_D[5]是最高位,Rx_D[0]是最低位。
而且由于是IQ解调,数据的传输顺序是:I_MSB,QMSB,I_LSB,Q_LSB
若在之前的Rx_FRAME和Tx_FRAME信号选择了50%占比的模式,那Tx_FRAME和Rx_FRAME就需要跟着转换,高电平时是MSB,低电平是LSB

SPI

SPI的配置寄存器
SPI可以配置成MSB,也可以配置成LSB,配置寄存器的D2和D5为0是MSB,为1是LSB,默认是MSB
SPI可以配置为3线SPI,也可以是4线SPI,默认是4线,D6和D1设置为0是4线,设置为1是3线
配置寄存器的D7和D0能重置所有寄存器,在设置其他寄存器之前,一定要将这个寄存器清零
** 状态输出管脚配置**
AD9364提供了8个引脚,用来实时显示芯片内部的状态。配置的函数为:static int32_t ad9361_ctrl_outs_setup(struct ad9361_rf_phy *phy, struct ctrl_outs_control *ctrl)
控制脚的映射关系可以用下面的map来改变,改变指针指向的行就可以改变映射方式。
在这里插入图片描述
在这里插入图片描述
然后用如下寄存器对pin进行使能,不使能的引脚保持low:
在这里插入图片描述

AD9364状态机(ENSM)

AD9364有TDD和FDD两种模式,并且可以通过两种方式控制,引脚控制或者SPI控制。

状态机转换图

TDD状态机(左),FDD状态机(右)
上图中灰色方块是临时态,会自动向下一状态转换。

状态机状态AD9364的工作状态
SLEEP刚刚上电 ,只有SPI的寄存器上了电
WAIT在wait基础上使能了基带时钟
ALERT在wait的基础上使能了rfPLL
Rx Tx FDD如果校正正确即可进入工作模式
控制方式

1、SPI控制:异步
SPI控制默认是关闭的,可以通过配置寄存器ENSM Config 1 register来使能。
状态转换关系

WAIT------->ALERTForce Alert State bit
ALERT----->RxForce Rx On bit on
Rx------>ALERT or WAITclear Rx On bit
ALERT----->Tx or FDDForce Tx On bit on
Tx or FDD------>ALERT or WAITclear Tx On bit

2、引脚控制:实时控制
引脚:ENABLE和TXNRX
注意脉冲宽度满足要求
引脚控制分为pulse模式和level模式,具体电平长度等可以直接参考AD9364 Reference Manual

3、SPI+引脚控制:可以在FDD的模式下独立开启Rx或Tx
操作分为三步:
1、设定FDD External Control Enable bit(0x015)
2、用SPI的方式将ENSM设定为FDD模式
3、用ENABLE和TXNRX采用pulse模式或者level模式

控制函数
int32_t ad9361_set_en_state_machine_mode (struct ad9361_rf_phy *phy, uint32_t mode)

AD9364滤波器配置

由于Rx与Tx相似,这里以Rx为例

Rx通路,前两个是模拟的,ADC后的是四个数字抽取滤波器,都可以被bypass

TIA LPF

单极点低通滤波器
可设置的截止频率范围:1MHz-70MHz
推荐设置:2.5*基带带宽

BB LPF

三阶巴特沃兹低通滤波器
可设定的截至频率范围:200kHz-39.2MHz
推荐设置:1.4*基带带宽

模拟带宽设置函数
int32_t ad9361_set_rx_rf_bandwidth (struct ad9361_rf_phy *phy, uint32_t bandwidth_hz)
DIGITAL FILTER

每个数字滤波器后都有一个抽取器,数字滤波器的时钟是ADC_CLK,都可以被bypass

HB3/DEC3

抽取系数:2or3
两个固定系数滤波器,二选一,其中:
HB3: [1, 4, 6, 4, 1] 最大值:16
DEC3: [55, 83, 0, −393, −580, 0, 1914, 4041, 5120, 4041,1914, 0, −580, −393, 0, 83, 55] 最大值:16384

HB2

抽取系数:2
系数: [−9, 0, 73, 128, 73, 0, −9] 最大值:256

HB1

抽取系数:2
系数: [−8, 0, 42, 0, −147, 0, 619, 1013, 619, 0, −147, 0, 42, 0, −8] 最大值:2048

FIR

抽取系数:1,2,4
系数抽头数:16:16:128
抽头系数:16位二进制补码
可配置增益:-12dB -6dB 0dB 6dB
自带增益:6dB
时钟:ADC_CLK或ADC_CLK/2
计算速度:每个时钟计算16个抽头
配置函数:int32_t ad9361_set_rx_fir_config (struct ad9361_rf_phy *phy, AD9361_RXFIRConfig fir_cfg)

总时延

t = N/(2*fs)

数字带宽设定函数
int32_t ad9361_calculate_rf_clock_chain(struct ad9361_rf_phy *phy,uint32_t tx_sample_rate,uint32_t rate_gov,uint32_t *rx_path_clks,uint32_t *tx_path_clks)

AD9364的增益控制

增益模式

AD9364一共有四种模式:manual,fast AGC,slow AGC,hybrid
控制函数:int32_t ad9361_set_rx_gain_control_mode (struct ad9361_rf_phy *phy, uint8_t ch, uint8_t gc_mode)
增益通路如下:
在这里插入图片描述
PS:ADC输入小于0.5V

增益表

每个接收机有自己的增益表,表中列代表不同的增益模块,每行中存放着他们的增益倍数,改变增益是通过改变指针指向的行决定的,如下:
在这里插入图片描述
增益表有两种模式:FULL TABLE|SPLIT TABLE
1、FULL TABLE
LPF之前的增益和LPF之后的增益在一张表内,控制方便,但是不够灵活。
2、SPLIT TABLE
LPF为界,分两个表。以LPF为界是因为LPF可以滤掉一部分杂波,滤掉后可以增益更大一些。
配置的函数:static int32_t ad9361_load_gt(struct ad9361_rf_phy *phy, uint64_t freq, uint32_t dest)

增益饱和检测

信号通路上有一系列功率检测器来查看信号的功率,主要有:
1、LMT(LNA,mixer,transimpedance)饱和检测
位置:模拟滤波器前
门限:上下可编程门限
MGC模式式可以通过control output pin来查看是否overload
在这里插入图片描述
2、ADC饱和检测
(没看懂……)

3、平均低功率检测
门限:0dB:-0.5dB:63.5dB
MGC模式下:低于门限flag立刻就显示

这些功率检测在增益改变后都得disable一下,需要等一段时间再开机,以上这些都是在int32_t ad9361_set_rx_gain_control_mode (struct ad9361_rf_phy *phy, uint8_t ch, uint8_t gc_mode)函数中调用static int32_t ad9361_gc_update(struct ad9361_rf_phy *phy)函数实现的

MGC增益控制

MGC模式中,控制gain index pointer就行。前面已经介绍了MGC的配置方法。
控制gain index pointer有两种方法:SPI写入或者通过control input pin移动(CTRL_IN0使得指针增加,CTRL_IN1使得指针减少),这两种方式的配置可以通过:int32_t ad9361_set_rx_gain_control_mode (struct ad9361_rf_phy *phy, uint8_t ch, uint8_t gc_mode)配置
在full table的条件下,上述可用
在split table的条件下,上述出现了一些变化,因为需要移动两个指针,用control input pin的方案需要调整。一种解决办法是SPI和控制脚同时控制,SPI选择表,控制脚控制方向。另一种可以引入AGC,AGC调整一个表,另一个表用control input pin调。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值