AD9361纯逻辑控制从0到1连载6-fast lock之profile寄存器设置

前面讲到每个profile由16个8bit寄存器组成,TX和RX的定义是一样的,下面列出RX profile每个寄存器的定义:
AD9361纯逻辑控制从0到1连载6-fast lock之profile寄存器设置_第1张图片
REG0 ~ REG4以及REG12[3:0]实际上是3个参数,lo_int( Integer Word),lo_frac(Fractional Word),lo_div(VCO Divider),射频频率计算公式如下:
freq=REF_PLL*(lo_int+lo_frac/8388593)/(2**(lo_div+1))
其中freq指工作的射频频率,REF_PLL指PLL的参考时钟(并非芯片输入时钟),REF_PLL确定后,lo_int和lo_frac决定VCO的频率,而射频工作频率由VCO/lo_div而来。另外一个约束条件是,VCO的工作频率必须在6G~12G之间,根据以上约束条件,一旦知道了射频频率,就可以计算出所有参数。
除REG12[3:0]和VCO_Varactor_Reference_Tcf(固定设置为7就可以了)以外,REG5 ~ REG13的其他参数都是通过查表获得。表中一共有53行,每行对应一个最佳性能的VCO Freqency。当你的VCO Frequency大于某行的VCO Frequency而小于上一行的VCO Frequency时,当前这行就是你要用的参数行。拿到参数后,按照寄存器定义,将参数填到这些寄存器对应的位置即可。
REG14,REG15是VCO校准的结果,当校准完成后,芯片会自动将校准结果填到这两个寄存器中。下面提供一个python程序,根据射频频率(起始频率,步进,结束频率),自动计算出每个频点应该设置的寄存器值

#!python3

import sys
import os
import shutil
import re
import openpyxl

#you should modify parameters below according to your design
#############################################################
START_FREQ=500000000	#hop start freqeuncy
END_FREQ=600000000		#hop end freqeuncy
STEP_FREQ=10000000		#hop resolution
REFIN=40000000			#clock input to chip pin
REFSCALE=2				#Ref Divider,only 1,0.5,0.25,2 allowd
sheet_name='FDD_80M'
REFCLK=REFIN*REFSCALE
#############################################################
#function definition
def freq_param_get(refclk,freq):
    lo_div=0
    lo_int=0
    lo_frac=0
    if freq>6000000000 or freq<46875000:
        return None
    freq_tmp=freq
    while freq_tmp<6000000000:
        freq_tmp=freq_tmp*2
        lo_div=lo_div+1
    lo_div=lo_div-1;
    mult_int_result=freq_tmp*int(2**64/refclk)
    lo_int=int(mult_int_result/(2**64))
    lo_frac=int(8388593*(freq_tmp/refclk-lo_int)+0.5)#4舍5入
    if lo_frac>=8388593:
        lo_frac=lo_frac-8388593
        lo_int=lo_int+1
        
    lo_freq=int(refclk*(lo_int+lo_frac/8388593)/(2**(lo_div+1))+0.5)
    vco_freq=int(lo_freq*(2**(lo_div+1))+0.5)
    
    return [lo_div,lo_int,lo_frac,lo_freq,vco_freq]

def loop_param_get(freq_param,loop_refer):
    vco_freq=freq_param[4]
    for i in range(len(loop_refer)):
        if vco_freq<loop_refer[i][4] and vco_freq>=loop_refer[i+1][4]:
            loop_param_index=loop_refer[i+1][3]-1
            loop_param=loop_refer[loop_param_index]
    return loop_param
###############################################################
#读取参数文件,将参数文件的内容转换为列表
workbook=openpyxl.load_workbook('ad9361_loop_reference_v3.xlsx')        
sheet=workbook[sheet_name]
loop_refer=[]
for row in range(2,55):
    tmp_list=[]
    for column in range(1,19):
        tmp_list.append(sheet.cell(row=row,column=column).value)
    loop_refer.append(tmp_list)
	
freq=START_FREQ
while freq<=END_FREQ:
    freq_param=freq_param_get(REFCLK,freq)
    lo_div=freq_param[0]
    lo_int=freq_param[1]
    lo_frac=freq_param[2]
    lo_freq=freq_param[3]
    vco_freq=freq_param[4]
    loop_param=loop_param_get(freq_param,loop_refer)
    VCO_Bias_Ref=loop_param[8]
    VCO_Varactor=loop_param[7]
    VCO_Bias_Tcf=loop_param[9]
    Charge_Pump_Current=loop_param[12]
    Charge_Pump_Current_Init=Charge_Pump_Current   
    Loop_Filter_R3=loop_param[17]
    Loop_Filter_R3_Init=Loop_Filter_R3
    Loop_Filter_C3=loop_param[16]
    Loop_Filter_C3_Init=Loop_Filter_C3
    Loop_Filter_C1=loop_param[14]
    Loop_Filter_C2=loop_param[13]
    Loop_Filter_R1=loop_param[15]
    Loop_Filter_R1_Init=Loop_Filter_R1
    VCO_Varactor_Reference_Tcf=7
    Rx_VCO_Divider=lo_div
    VCO_Cal_Offset=loop_param[10]
    VCO_Varactor_Reference=loop_param[11]
    REG0=lo_int&0xff
    REG1=(lo_div>>8)&0xff
    REG2=lo_frac&0xff
    REG3=(lo_frac>>8)&0xff
    REG4=(lo_frac>>16)&0xff
    REG5=(VCO_Bias_Ref<<4)+VCO_Varactor
    REG6=(VCO_Bias_Tcf<<6)+Charge_Pump_Current_Init
    REG7=Charge_Pump_Current
    REG8=(Loop_Filter_R3<<4)+Loop_Filter_R3_Init
    REG9=(Loop_Filter_C3<<4)+Loop_Filter_C3_Init
    REG10=(Loop_Filter_C1<<4)+Loop_Filter_C2
    REG11=(Loop_Filter_R1<<4)+Loop_Filter_R1_Init
    REG12=(VCO_Varactor_Reference_Tcf<<4)+Rx_VCO_Divider
    REG13=(VCO_Cal_Offset<<4)+VCO_Varactor_Reference
    REG14=0x00
    REG15=0x00	
    reg_map=[REG0,REG1,REG2,REG3,REG4,REG5,REG6,REG7,REG8,REG9,REG10,REG11,REG12,REG13,REG14,REG15]
    
    print_result=1
    if print_result:
        reg_map.reverse()        
        for i in reg_map: 
            print('%02X'%i,end='')
        print('')
        reg_map.reverse()
    freq=freq+STEP_FREQ
sys.exit()

打印的结果是这样的,一共128bit,用16进制显示。
AD9361纯逻辑控制从0到1连载6-fast lock之profile寄存器设置_第2张图片
注意下,我这里是将SynthLUT_80_FDD_v3.txt等6个txt文件写到excel表格中方便python程序调用。
上面的python代码需要有对应的verilog代码才能在FPGA上实现,读者可以根据python的流程自己写一下。下章节讲解如何具体将这些寄存器写到芯片,并开启校准获得校准结果

链接:https://pan.baidu.com/s/1QFf-576UAVBNP5XrA5V72Q
提取码:27ok
–来自百度网盘超级会员V3的分享

你可能感兴趣的:(AD9361纯逻辑控制,AD9361,AD9363,SDR,软件无线电)