update zc706_cx9261a_demo vitis project, add api to help debug
This commit is contained in:
+1
-1
Submodule scripts updated: a3f08704e6...eec2f030d8
@@ -4,8 +4,8 @@
|
|||||||
"hw_design": "../system_top.xsa",
|
"hw_design": "../system_top.xsa",
|
||||||
"hw_version": "zc706_cx9261a_demo-HW-0.0.1",
|
"hw_version": "zc706_cx9261a_demo-HW-0.0.1",
|
||||||
"apps": {
|
"apps": {
|
||||||
"sjl_dj_app_df": {
|
"zc706_cx9261a_app": {
|
||||||
"sources": ["source/"],
|
"sources": ["source_zc706_cx9261a/"],
|
||||||
"target_cpu": "ps7_cortexa9_0",
|
"target_cpu": "ps7_cortexa9_0",
|
||||||
"os": "standalone",
|
"os": "standalone",
|
||||||
"language": "C",
|
"language": "C",
|
||||||
@@ -15,15 +15,25 @@
|
|||||||
},
|
},
|
||||||
"build_config": {
|
"build_config": {
|
||||||
"debug": {
|
"debug": {
|
||||||
"include-path": ["source/include"],
|
"include-path": ["source_zc706_cx9261a/include"],
|
||||||
"libraries": ["cx9261a_c_dbg", "stdc++", "m"],
|
"libraries": ["cx9261a_c_dbg", "stdc++", "m"],
|
||||||
"library-search-path": ["lib"]
|
"library-search-path": ["source_zc706_cx9261a/drivers/rf-transceiver/cx9261a/lib"]
|
||||||
},
|
},
|
||||||
"release": {
|
"release": {
|
||||||
"include-path": ["source/include"],
|
"include-path": ["source_zc706_cx9261a/include"],
|
||||||
"libraries": ["cx9261a_c", "stdc++", "m"],
|
"libraries": ["cx9261a_c", "stdc++", "m"],
|
||||||
"library-search-path": ["lib"]
|
"library-search-path": ["source_zc706_cx9261a/drivers/rf-transceiver/cx9261a/lib"]
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cx9261_api_app": {
|
||||||
|
"sources": ["source_cx9261_api_1_9_0/"],
|
||||||
|
"target_cpu": "ps7_cortexa9_0",
|
||||||
|
"os": "standalone",
|
||||||
|
"language": "C++",
|
||||||
|
"mem_layout" : {
|
||||||
|
"heap_size": "0x80000",
|
||||||
|
"stack_size": "0x4000"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2188
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,546 @@
|
|||||||
|
/**
|
||||||
|
* @file cx9261adriver.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CX9261ADRIVER_CX9261ADRIVER_H
|
||||||
|
#define CX9261ADRIVER_CX9261ADRIVER_H
|
||||||
|
|
||||||
|
#define VERSION 1.9.0
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
// 如果不需要输出日志内容,注释掉下面的宏定义
|
||||||
|
#define USE_LOGGING
|
||||||
|
|
||||||
|
#ifdef USE_LOGGING
|
||||||
|
# define LOGGING(x) logging(x);
|
||||||
|
#else
|
||||||
|
# define LOGGING(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace CX9261A {
|
||||||
|
#ifdef USE_LOGGING
|
||||||
|
/**
|
||||||
|
* @brief 输出日志的函数
|
||||||
|
* @param msg 要输出的内容
|
||||||
|
*/
|
||||||
|
void logging(const std::string& msg);
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
* @brief 需要实现的函数,实现SPI写入寄存器功能
|
||||||
|
* @param address 要写入的寄存器地址
|
||||||
|
* @param value 要写入的寄存器值
|
||||||
|
*/
|
||||||
|
void writeSpi(int address, int value);
|
||||||
|
/**
|
||||||
|
* @brief 需要实现的函数,实现SPI读取寄存器功能
|
||||||
|
* @param address 要读取的寄存器地址
|
||||||
|
* @return 返回的寄存器值
|
||||||
|
*/
|
||||||
|
int readSpi(int address);
|
||||||
|
/**
|
||||||
|
* @brief 需要实现的函数,实现等待功能
|
||||||
|
* @param ms 等待时间,单位毫秒
|
||||||
|
*/
|
||||||
|
void pause(double ms);
|
||||||
|
/**
|
||||||
|
* @brief 需要实现的函数,实现配置FPGA对应寄存器功能
|
||||||
|
* @param pin 寄存器地址
|
||||||
|
* @param value 寄存器值
|
||||||
|
*/
|
||||||
|
void setPin(int pin, int value);
|
||||||
|
/**
|
||||||
|
* @brief 初始化芯片状态,写入与具体配置无关的寄存器值
|
||||||
|
*/
|
||||||
|
void initialChip();
|
||||||
|
/**
|
||||||
|
* @brief 初始化电源配置,如果只自定义配置部分模式下的电源管理,在自定义配置之前需要先调用此函数
|
||||||
|
*/
|
||||||
|
void initialPowerConfig(const CX9261AConfiguration& config);
|
||||||
|
/**
|
||||||
|
* @brief 初始化BBPLL相关寄存器,如果调用了initialChip,则无需单独调用此函数
|
||||||
|
*/
|
||||||
|
void initialBBPLL();
|
||||||
|
/**
|
||||||
|
* @brief 初始化PLL1相关寄存器,如果调用了initialChip,则无需单独调用此函数
|
||||||
|
*/
|
||||||
|
void initialPLL1();
|
||||||
|
/**
|
||||||
|
* @brief 初始化PLL2相关寄存器,如果调用了initialChip,则无需单独调用此函数
|
||||||
|
*/
|
||||||
|
void initialPLL2();
|
||||||
|
/**
|
||||||
|
* @brief 初始化PLL3相关寄存器,如果调用了initialChip,则无需单独调用此函数
|
||||||
|
*/
|
||||||
|
void initialPLL3();
|
||||||
|
/**
|
||||||
|
* @brief 初始化PLL4相关寄存器,如果调用了initialChip,则无需单独调用此函数
|
||||||
|
*/
|
||||||
|
void initialPLL4();
|
||||||
|
/**
|
||||||
|
* @brief 初始化PLL5相关寄存器,如果调用了initialChip,则无需单独调用此函数
|
||||||
|
*/
|
||||||
|
void initialPLL5();
|
||||||
|
/**
|
||||||
|
* @brief 配置受参考时钟频率影响的寄存器
|
||||||
|
* @param ref 参考时钟频率,单位MHz
|
||||||
|
*/
|
||||||
|
void configRef(double ref);
|
||||||
|
/**
|
||||||
|
* @brief 配置时钟相关寄存器,包括ADC和BBPLL
|
||||||
|
* @param config CX9261A参数结构体
|
||||||
|
*/
|
||||||
|
void configBBPLL(const CX9261AConfiguration& config);
|
||||||
|
/**
|
||||||
|
* @brief BBPLL AFC
|
||||||
|
* @return 是否锁定
|
||||||
|
*/
|
||||||
|
bool afcBBPll();
|
||||||
|
/**
|
||||||
|
* @brief 配置PLL1频率
|
||||||
|
* @param lo 目标频率
|
||||||
|
* @param clock 时钟结构体,使用其中的ref和refDoubler属性
|
||||||
|
*/
|
||||||
|
void configPll1(double lo, const Clock& clock);
|
||||||
|
/**
|
||||||
|
* @brief Pll1 AFC
|
||||||
|
* @return 是否锁定
|
||||||
|
*/
|
||||||
|
bool afcPll1();
|
||||||
|
/**
|
||||||
|
* @brief 配置PLL2频率
|
||||||
|
* @param lo 目标频率
|
||||||
|
* @param clock 时钟结构体,使用其中的ref和refDoubler属性
|
||||||
|
*/
|
||||||
|
void configPll2(double lo, const Clock& clock);
|
||||||
|
/**
|
||||||
|
* @brief Pll2 AFC
|
||||||
|
* @return 是否锁定
|
||||||
|
*/
|
||||||
|
bool afcPll2();
|
||||||
|
/**
|
||||||
|
* @brief 配置PLL3频率
|
||||||
|
* @param lo 目标频率
|
||||||
|
* @param clock 时钟结构体,使用其中的ref和refDoubler属性
|
||||||
|
*/
|
||||||
|
void configPll3(double lo, const Clock& clock);
|
||||||
|
/**
|
||||||
|
* @brief Pll3 AFC
|
||||||
|
* @return 是否锁定
|
||||||
|
*/
|
||||||
|
bool afcPll3();
|
||||||
|
/**
|
||||||
|
* @brief 配置PLL4频率
|
||||||
|
* @param lo 目标频率
|
||||||
|
* @param clock 时钟结构体,使用其中的ref和refDoubler属性
|
||||||
|
*/
|
||||||
|
void configPll4(double lo, const Clock& clock);
|
||||||
|
/**
|
||||||
|
* @brief Pll4 AFC
|
||||||
|
* @return 是否锁定
|
||||||
|
*/
|
||||||
|
bool afcPll4();
|
||||||
|
/**
|
||||||
|
* @brief 配置PLL5频率
|
||||||
|
* @param lo 目标频率
|
||||||
|
* @param clock 时钟结构体,使用其中的ref和refDoubler属性
|
||||||
|
*/
|
||||||
|
void configPll5(double lo, const Clock& clock);
|
||||||
|
/**
|
||||||
|
* @brief Pll5 AFC
|
||||||
|
* @return 是否锁定
|
||||||
|
*/
|
||||||
|
bool afcPll5();
|
||||||
|
/**
|
||||||
|
* @brief 配置AGC模式
|
||||||
|
* @param mode 模式0~13
|
||||||
|
*/
|
||||||
|
void configAGCMode(int mode);
|
||||||
|
/**
|
||||||
|
* @brief 配置AGC PDT
|
||||||
|
* @param pdt AGCPDT结构体
|
||||||
|
*/
|
||||||
|
void configAGCPDT(const AGCPDT& pdt);
|
||||||
|
/**
|
||||||
|
* @brief 配置AGC LMT
|
||||||
|
* @param lmt AGCLMT结构体
|
||||||
|
*/
|
||||||
|
void configAGCLMT(const AGCLMT& lmt);
|
||||||
|
/**
|
||||||
|
* @brief 配置AGC DIG
|
||||||
|
* @param dig AGCDIG结构体
|
||||||
|
*/
|
||||||
|
void configAGCDIG(const AGCDIG& dig);
|
||||||
|
/**
|
||||||
|
* @brief 配置AGC
|
||||||
|
* @param agc AGC结构体
|
||||||
|
*/
|
||||||
|
void configAGC(const AGC& agc);
|
||||||
|
/**
|
||||||
|
* @brief 配置片内处理器,仅在使用需要处理器辅助的校准方法时需要开启处理器
|
||||||
|
* @param on 开启/关闭
|
||||||
|
*/
|
||||||
|
void configRISCV(bool on);
|
||||||
|
/**
|
||||||
|
* @brief 配置温补
|
||||||
|
* @param mode 温补模式 DAC/Band
|
||||||
|
*/
|
||||||
|
void configTemperatureCompensation(TemperatureComp mode);
|
||||||
|
/**
|
||||||
|
* @brief ADC校准
|
||||||
|
* @param adc ADC速率
|
||||||
|
*/
|
||||||
|
void configADCCalib(double adc);
|
||||||
|
/**
|
||||||
|
* @brief Flash校准
|
||||||
|
*/
|
||||||
|
void configFlashCalib();
|
||||||
|
/**
|
||||||
|
* @brief QEC校准会改变部分寄存器配置,在进行校准之前需要保存这部分寄存器,校准后恢复
|
||||||
|
* @return 包含寄存器地址和值的map
|
||||||
|
*/
|
||||||
|
std::map<int, int> beforeQecState();
|
||||||
|
/**
|
||||||
|
* @brief 恢复QEC校准过程中改变的寄存器
|
||||||
|
* @param state beforeQecState函数返回的map
|
||||||
|
*/
|
||||||
|
void restoreQecState(const std::map<int, int>& state);
|
||||||
|
/**
|
||||||
|
* @brief 根据pll来源配置校准模式下的电源管理
|
||||||
|
* @param pllSource PllSource结构体
|
||||||
|
*/
|
||||||
|
void preparePowerForRxCalib(const PllSource& pllSource);
|
||||||
|
/**
|
||||||
|
* @brief 调整校准时Pll的配置
|
||||||
|
* @param config CX9261A配置结构体
|
||||||
|
* @param chan 要进行校准的通道
|
||||||
|
*/
|
||||||
|
void preparePllForRxCalib(const CX9261AConfiguration& config, RxChannel chan);
|
||||||
|
/**
|
||||||
|
* @brief 等待RxTST窄带校准结束,可重写
|
||||||
|
* @return 校准是否结束
|
||||||
|
*/
|
||||||
|
bool waitRxTSTFinished();
|
||||||
|
/**
|
||||||
|
* @brief RX时域统计校准
|
||||||
|
* @param chan 校准的RX通道
|
||||||
|
*/
|
||||||
|
void rxTSTCalib(RxChannel chan);
|
||||||
|
/**
|
||||||
|
* @brief RX延时线校准
|
||||||
|
* @param fs ADC采样率
|
||||||
|
* @param chan 校准的RX通道
|
||||||
|
*/
|
||||||
|
void rxDelayCalib(double fs, RxChannel chan);
|
||||||
|
/**
|
||||||
|
* @brief DC Tracking
|
||||||
|
* @param config CX9261A配置结构体
|
||||||
|
*/
|
||||||
|
void configDcCalib(const Calib& config);
|
||||||
|
void configDcCalibMethod(DCCalibMethod method);
|
||||||
|
void configDcTrackingLength(int length);
|
||||||
|
void configDcHighPassFactor(int factor);
|
||||||
|
/**
|
||||||
|
* @brief Rx校准
|
||||||
|
* @param config CX9261A配置结构体
|
||||||
|
* @param chan 要进行校准的通道
|
||||||
|
*/
|
||||||
|
void rxCalib(const CX9261AConfiguration& config, RxChannel chan);
|
||||||
|
/**
|
||||||
|
* @brief 选择校准方法
|
||||||
|
* @param calib 校准结构体
|
||||||
|
*/
|
||||||
|
void configCalibMethod(const Calib& calib);
|
||||||
|
/**
|
||||||
|
* @brief 读取当前Rx chan通道的校准值
|
||||||
|
* @param chan Rx通道
|
||||||
|
* @return 校准值结构体
|
||||||
|
*/
|
||||||
|
CalibPredis readRxCalibPredis(RxChannel chan);
|
||||||
|
/**
|
||||||
|
* @brief 储存校准值
|
||||||
|
* @param index 第index组校准值
|
||||||
|
* @param chan 接收通道
|
||||||
|
* @param pll 使用的PLL
|
||||||
|
*/
|
||||||
|
void saveRxCalibPredis(unsigned char index, RxChannel chan, LoSource pll);
|
||||||
|
/**
|
||||||
|
* @brief 加载保存的校准值
|
||||||
|
* @param index 第index组校准值
|
||||||
|
* @param chan 指定加载校准值的通道
|
||||||
|
* @param pll 使用的PLL
|
||||||
|
*/
|
||||||
|
void loadRxCalibPredis(unsigned char index, RxChannel chan, LoSource pll);
|
||||||
|
/**
|
||||||
|
* @brief Rx窄带多点校准
|
||||||
|
* @param config CX9261A配置结构体
|
||||||
|
* @param points 校准点
|
||||||
|
* @param chan 接收通道
|
||||||
|
*/
|
||||||
|
void configRxMultiPointsQec(const CX9261AConfiguration& config, const std::vector<double>& points, RxChannel chan);
|
||||||
|
/**
|
||||||
|
* @brief 根据pll来源配置校准模式下的电源管理
|
||||||
|
* @param pllSource PllSource结构体
|
||||||
|
*/
|
||||||
|
void preparePowerForTxCalib(const PllSource& pllSource);
|
||||||
|
/**
|
||||||
|
* @brief 调整校准时Pll的配置
|
||||||
|
* @param config CX9261A配置结构体
|
||||||
|
*/
|
||||||
|
void preparePllForTxCalib(const CX9261AConfiguration& config);
|
||||||
|
/**
|
||||||
|
* @brief TX二分法QEC校准
|
||||||
|
* @param f0 校准音频率
|
||||||
|
* @param fs adc频率
|
||||||
|
*/
|
||||||
|
void txBisectionQecCalib(double f0, double fs);
|
||||||
|
/**
|
||||||
|
* @brief TX时域统计法校准
|
||||||
|
* @param config CX9261A配置结构体
|
||||||
|
* @param chan 要校准的通道
|
||||||
|
*/
|
||||||
|
void txTSTCalib(const CX9261AConfiguration& config, TxChannel chan);
|
||||||
|
/**
|
||||||
|
* @brief TX二分法DC校准
|
||||||
|
* @param f0 校准音频率
|
||||||
|
* @param fs adc频率
|
||||||
|
*/
|
||||||
|
void txBisectionDcCalib(double f0, double fs);
|
||||||
|
/**
|
||||||
|
* @brief Tx多点校准
|
||||||
|
* @param config CX9261A配置结构体
|
||||||
|
* @param points 校准点
|
||||||
|
*/
|
||||||
|
void configTxMultiPointsQec(const CX9261AConfiguration& config, const std::vector<double>& points);
|
||||||
|
/**
|
||||||
|
* @brief Tx通道校准
|
||||||
|
* @param config CX9261A配置结构体
|
||||||
|
*/
|
||||||
|
void txCalib(const CX9261AConfiguration& config);
|
||||||
|
/**
|
||||||
|
* @brief 储存校准值
|
||||||
|
* @param index 第index组校准值
|
||||||
|
* @param chan 发射通道
|
||||||
|
* @param pll pll
|
||||||
|
*/
|
||||||
|
void saveTxCalibPredis(unsigned char index, TxChannel chan, LoSource pll);
|
||||||
|
/**
|
||||||
|
* @brief 加载保存的校准值
|
||||||
|
* @param index 第index组校准值
|
||||||
|
* @param chan 指定加载校准值的通道
|
||||||
|
* @param pll 指定加载校准值对应的PLL
|
||||||
|
*/
|
||||||
|
void loadTxCalibPredis(unsigned char index, TxChannel chan, LoSource pll);
|
||||||
|
/**
|
||||||
|
* @brief Qec校准顶层函数,内部根据配置选择使用对应方法进行校准
|
||||||
|
* @param config CX9261A配置结构体
|
||||||
|
*/
|
||||||
|
void configQecCalib(const CX9261AConfiguration& config);
|
||||||
|
/**
|
||||||
|
* @brief 配置TX NCO相关寄存器
|
||||||
|
* @param nco TX NCO配置结构体
|
||||||
|
* @param fs adc速率
|
||||||
|
*/
|
||||||
|
void configTxNco(const TxNCO& nco, double fs);
|
||||||
|
/**
|
||||||
|
* @brief 配置TX NCO BIST模式
|
||||||
|
* @param bist 开启/关闭BIST
|
||||||
|
*/
|
||||||
|
void configTxBIST(bool bist);
|
||||||
|
/**
|
||||||
|
* @brief 配置TX NCO频率
|
||||||
|
* @param freq 混频频率
|
||||||
|
* @param fs adc抽取后速率
|
||||||
|
*/
|
||||||
|
void configTxNcoFreq(double freq, double fs);
|
||||||
|
/**
|
||||||
|
* @brief 配置RX NCO相关寄存器
|
||||||
|
* @param nco RX NCO配置结构体
|
||||||
|
* @param fs adc速率
|
||||||
|
*/
|
||||||
|
void configRxNco(const RxNCO& nco, double fs);
|
||||||
|
/**
|
||||||
|
* @brief 配置Rx NCO模式
|
||||||
|
* @param mode NCO模式:Bypass/BIST/Up/Down
|
||||||
|
*/
|
||||||
|
void configRxNcoMode(NCOMode mode);
|
||||||
|
/**
|
||||||
|
* @brief 配置Rx NCO模式
|
||||||
|
* @param mode NCO模式:Master/Slaver
|
||||||
|
*/
|
||||||
|
void configRxNcoMS(NCOMode mode);
|
||||||
|
/**
|
||||||
|
* @brief 配置Rx NCO频率
|
||||||
|
* @param freq 混频频率
|
||||||
|
* @param fs adc速率
|
||||||
|
*/
|
||||||
|
void configRxNcoFreq(double freq, double fs);
|
||||||
|
/**
|
||||||
|
* @brief 配置接口相关寄存器
|
||||||
|
* @param interface Interface配置结构体
|
||||||
|
*/
|
||||||
|
void configInterface(const Interface& interface);
|
||||||
|
/**
|
||||||
|
* @brief 配置PLL来源
|
||||||
|
* @param pllSource PLlSource结构体
|
||||||
|
*/
|
||||||
|
void configPllSource(const PllSource& pllSource);
|
||||||
|
/**
|
||||||
|
* @brief 切换电源模式
|
||||||
|
* @param pm 电源模式
|
||||||
|
*/
|
||||||
|
void configPowerMode(PowerMode pm);
|
||||||
|
/**
|
||||||
|
* @brief 配置电源管理
|
||||||
|
* @param power 电源配置结构体
|
||||||
|
* @param pm 电源模式
|
||||||
|
*/
|
||||||
|
void configPowerPins(const Power& power, PowerMode pm);
|
||||||
|
/**
|
||||||
|
* @brief 配置参考倍频器
|
||||||
|
* @param doubler 倍频器开关
|
||||||
|
* @param ref 参考时钟频率,单位MHz
|
||||||
|
*/
|
||||||
|
void configRefDoubler(bool doubler, double ref);
|
||||||
|
/**
|
||||||
|
* @brief 初始化通道,调用initialChip函数会初始化RX1,RX2,RX3三个通道
|
||||||
|
* @param chan 通道 RX1/RX2/RX3
|
||||||
|
*/
|
||||||
|
void initialRxChannel(RxChannel chan);
|
||||||
|
/**
|
||||||
|
* @brief 配置Rx带宽
|
||||||
|
* @note 只改变Rx带宽会导致通道增益改变,建议使用configRxChannel函数进行带宽调整
|
||||||
|
* @param bandwidth 带宽,单位(MHz)
|
||||||
|
* @param chan 通道 Rx1/Rx2/Rx3
|
||||||
|
*/
|
||||||
|
void configRxBandwidth(double bandwidth, RxChannel chan);
|
||||||
|
/**
|
||||||
|
* @brief 配置Rx TIA
|
||||||
|
* @note 只改变TIA会导致通道带宽改变,建议使用configRxChannel函数进行TIA调整
|
||||||
|
* @param tia tia档位
|
||||||
|
* @param chan 通道 Rx1/Rx2/Rx3
|
||||||
|
*/
|
||||||
|
void configRxTIA(int tia, RxChannel chan);
|
||||||
|
/**
|
||||||
|
* @brief 配置Rx Mixer
|
||||||
|
* @param mixer mixer档位
|
||||||
|
*/
|
||||||
|
void configRxMixer(int mixer);
|
||||||
|
/**
|
||||||
|
* @brief 配置Rx通道,包含TIA,Mixer以及Bandwidth
|
||||||
|
* @param config RxConfig结构体
|
||||||
|
* @param chan Rx1/Rx2/Rx3
|
||||||
|
*/
|
||||||
|
void configRxChannel(const RxConfig& config, RxChannel chan);
|
||||||
|
/**
|
||||||
|
* @brief 配置Rx FIR滤波器抽取倍数
|
||||||
|
* @param fir 抽取倍数 0(Bypass)/1/2/3/4/8
|
||||||
|
*/
|
||||||
|
void configRxFIR(int fir);
|
||||||
|
/**
|
||||||
|
* @brief 配置Rx HBF1滤波器抽取倍数
|
||||||
|
* @param hbf 抽取倍数 0(Bypass)/2
|
||||||
|
*/
|
||||||
|
void configRxHBF1(int hbf);
|
||||||
|
/**
|
||||||
|
* @brief 配置Rx HBF2滤波器抽取倍数
|
||||||
|
* @param hbf 抽取倍数 0(Bypass)/2
|
||||||
|
*/
|
||||||
|
void configRxHBF2(int hbf);
|
||||||
|
/**
|
||||||
|
* @brief 配置Rx HBF3滤波器抽取倍数
|
||||||
|
* @param hbf 抽取倍数 0(Bypass)/2/3
|
||||||
|
*/
|
||||||
|
void configRxHBF3(int hbf);
|
||||||
|
/**
|
||||||
|
* @brief 配置Rx CIC滤波器
|
||||||
|
* @param cic 抽取倍数 0(Bypass)/20
|
||||||
|
*/
|
||||||
|
void configRxCIC(int cic);
|
||||||
|
/**
|
||||||
|
* @brief 配置Rx滤波器
|
||||||
|
* @param filters Filters结构体
|
||||||
|
*/
|
||||||
|
void configRxFilters(const Filters& filters);
|
||||||
|
/**
|
||||||
|
* @brief 配置Rx FIR滤波器系数
|
||||||
|
* @param coe 滤波器系数,长度为16的整倍数,最大128
|
||||||
|
*/
|
||||||
|
void configRxFIRCoe(const std::vector<double>& coe);
|
||||||
|
/**
|
||||||
|
* @brief 配置Tx带宽
|
||||||
|
* @param bandwidth 带宽,单位(MHz)
|
||||||
|
* @param chan 通道 TX1/TX2
|
||||||
|
*/
|
||||||
|
void configTxBandwidth(double bandwidth, TxChannel chan);
|
||||||
|
/**
|
||||||
|
* @brief 配置Tx Mixer
|
||||||
|
* @param mixer 混频器值
|
||||||
|
* @param chan TX1/TX2
|
||||||
|
*/
|
||||||
|
void configTxMixer(int mixer, TxChannel chan);
|
||||||
|
/**
|
||||||
|
* @brief 初始化Tx通道
|
||||||
|
* @param chan 通道 TX1/TX2
|
||||||
|
*/
|
||||||
|
void initialTxChannel(TxChannel chan);
|
||||||
|
/**
|
||||||
|
* @brief 根据Tx通道的本振频率,配置对应的参数
|
||||||
|
* @param lo 本振频率,单位(MHz)
|
||||||
|
* @param chan 通道(Tx1/Tx2)
|
||||||
|
*/
|
||||||
|
void configTxChannelFrequency(double lo, TxChannel chan);
|
||||||
|
/**
|
||||||
|
* @brief 配置Tx通道,Mixer以及Bandwidth
|
||||||
|
* @param config TxConfig结构体
|
||||||
|
* @param chan Tx1/Tx2
|
||||||
|
*/
|
||||||
|
void configTxChannel(const TxConfig& config, TxChannel chan);
|
||||||
|
/**
|
||||||
|
* @brief 配置Tx FIR滤波器插值倍数
|
||||||
|
* @param fir 插值倍数 0(Bypass)/1/2/3/4/8
|
||||||
|
*/
|
||||||
|
void configTxFIR(int fir);
|
||||||
|
/**
|
||||||
|
* @brief 配置Tx HBF1滤波器插值倍数
|
||||||
|
* @param hbf 插值倍数 0(Bypass)/2
|
||||||
|
*/
|
||||||
|
void configTxHBF1(int hbf);
|
||||||
|
/**
|
||||||
|
* @brief 配置Tx HBF2滤波器插值倍数
|
||||||
|
* @param hbf 插值倍数 0(Bypass)/2
|
||||||
|
*/
|
||||||
|
void configTxHBF2(int hbf);
|
||||||
|
/**
|
||||||
|
* @brief 配置Tx HBF3滤波器插值倍数
|
||||||
|
* @param hbf 插值倍数 0(Bypass)/2/3
|
||||||
|
*/
|
||||||
|
void configTxHBF3(int hbf);
|
||||||
|
/**
|
||||||
|
* @brief 配置Tx CIC滤波器
|
||||||
|
* @param cic 插值倍数 0(Bypass)/8/20/32/80
|
||||||
|
*/
|
||||||
|
void configTxCIC(int cic);
|
||||||
|
/**
|
||||||
|
* @brief 配置Tx滤波器
|
||||||
|
* @param filters Filters结构体
|
||||||
|
*/
|
||||||
|
void configTxFilters(const Filters& filters);
|
||||||
|
/**
|
||||||
|
* @brief 配置Tx FIR滤波器系数
|
||||||
|
* @param coe 滤波器系数,长度为16的整倍数,最大128
|
||||||
|
*/
|
||||||
|
void configTxFIRCoe(const std::vector<double>& coe);
|
||||||
|
/**
|
||||||
|
* @brief 读取当前Tx chan通道的校准值
|
||||||
|
* @param chan Tx通道
|
||||||
|
* @return 校准值结构体
|
||||||
|
*/
|
||||||
|
CalibPredis readTxCalibPredis(TxChannel chan);
|
||||||
|
/**
|
||||||
|
* @brief 此函数为Demo板配套配置函数,用于配置FPGA接口,用户开发自己的程序时应重写对应功能
|
||||||
|
* @param interface Interface结构体
|
||||||
|
*/
|
||||||
|
void configFPGA(const Interface& interface);
|
||||||
|
} // namespace CX9261A
|
||||||
|
|
||||||
|
#endif // CX9261ADRIVER_CX9261ADRIVER_H
|
||||||
@@ -0,0 +1,424 @@
|
|||||||
|
/**
|
||||||
|
* @file defs.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CX9261ADRIVER_DEFS_H
|
||||||
|
#define CX9261ADRIVER_DEFS_H
|
||||||
|
|
||||||
|
#include <bitset>
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#ifdef interface
|
||||||
|
# undef interface
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace CX9261A {
|
||||||
|
/**
|
||||||
|
* @brief 芯片工作模式
|
||||||
|
*/
|
||||||
|
enum class WorkMode : std::uint8_t { Rx, Tx, FDD };
|
||||||
|
/**
|
||||||
|
* @brief 收发数据通道数量
|
||||||
|
* @note 此模式并不代表使用几个通道进行收发
|
||||||
|
*/
|
||||||
|
enum class TrMode : std::uint8_t { R1T1, R2T2 };
|
||||||
|
/**
|
||||||
|
* @brief 收发接口通道数量
|
||||||
|
*/
|
||||||
|
enum class PortMode : std::uint8_t { Single, Dual };
|
||||||
|
/**
|
||||||
|
* @brief 接口模式:
|
||||||
|
* CMOS CMOS接口模式,
|
||||||
|
* LVDS_S LVDS顺序模式,
|
||||||
|
* LVDS_E LVDS奇偶模式
|
||||||
|
*/
|
||||||
|
enum class IOMode : std::uint8_t { CMOS, LVDS_S, LVDS_E };
|
||||||
|
/**
|
||||||
|
* @brief 本振来源
|
||||||
|
*/
|
||||||
|
enum class LoSource : std::uint8_t {
|
||||||
|
Pll1 = 0b00001,
|
||||||
|
Pll2 = 0b00010,
|
||||||
|
Pll3 = 0b00100,
|
||||||
|
Pll4 = 0b01000,
|
||||||
|
Pll5 = 0b10000,
|
||||||
|
Off = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::string toString(const LoSource source)
|
||||||
|
{
|
||||||
|
switch (source) {
|
||||||
|
case LoSource::Pll1:
|
||||||
|
return "Pll1";
|
||||||
|
case LoSource::Pll2:
|
||||||
|
return "Pll2";
|
||||||
|
case LoSource::Pll3:
|
||||||
|
return "Pll3";
|
||||||
|
case LoSource::Pll4:
|
||||||
|
return "Pll4";
|
||||||
|
case LoSource::Pll5:
|
||||||
|
return "Pll5";
|
||||||
|
default:
|
||||||
|
return "Off";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief 接收通道
|
||||||
|
*/
|
||||||
|
enum class RxChannel : std::uint8_t { Rx1 = 1, Rx2, Rx3 };
|
||||||
|
|
||||||
|
inline std::string toString(const RxChannel chan)
|
||||||
|
{
|
||||||
|
switch (chan) {
|
||||||
|
case RxChannel::Rx1:
|
||||||
|
return "Rx1";
|
||||||
|
case RxChannel::Rx2:
|
||||||
|
return "Rx2";
|
||||||
|
case RxChannel::Rx3:
|
||||||
|
return "Rx3";
|
||||||
|
default:
|
||||||
|
return "Unknown Channel";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief 发射通道
|
||||||
|
*/
|
||||||
|
enum class TxChannel : std::uint8_t { Tx1 = 1, Tx2 };
|
||||||
|
|
||||||
|
inline std::string toString(const TxChannel chan)
|
||||||
|
{
|
||||||
|
switch (chan) {
|
||||||
|
case TxChannel::Tx1:
|
||||||
|
return "Tx1";
|
||||||
|
case TxChannel::Tx2:
|
||||||
|
return "Tx2";
|
||||||
|
default:
|
||||||
|
return "Unknown Channel";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief 电源模式
|
||||||
|
*/
|
||||||
|
enum class PowerMode : std::uint8_t { Shutdown = 0, Sleep, Alert, Calib, Receive, Transmit, Duplex, Obs };
|
||||||
|
/**
|
||||||
|
* @brief NCO模式
|
||||||
|
*/
|
||||||
|
enum class NCOMode : std::uint8_t { Bypass = 0, Up, Down, BIST, Master, Slaver };
|
||||||
|
/**
|
||||||
|
* @brief 温补模式 DAC: DAC模式 Band: 跳子带模式
|
||||||
|
*/
|
||||||
|
enum class TemperatureComp : std::uint8_t { DAC = 0, Band };
|
||||||
|
/**
|
||||||
|
* @brief 校准方法 TST: 时域统计 Rx通道使用, Bisec: 二分法 Tx通道使用, MultiPoints: 多点校准
|
||||||
|
*/
|
||||||
|
enum class CalibMethod : std::uint8_t { TST = 0, Bisec, MultiPoints, Tracking };
|
||||||
|
/**
|
||||||
|
* @brief DC校准方法 Tracking: 跟踪校准 HighPass: 高通滤波器滤掉直流
|
||||||
|
*/
|
||||||
|
enum class DCCalibMethod : std::uint8_t { Tracking = 0, HighPass };
|
||||||
|
/**
|
||||||
|
* @brief AFC等待延时,单位ms
|
||||||
|
*/
|
||||||
|
constexpr double delay = 100;
|
||||||
|
/**
|
||||||
|
* @brief QEC等待延时,单位ms
|
||||||
|
*/
|
||||||
|
constexpr double qecDelay = 500;
|
||||||
|
/**
|
||||||
|
* @brief 接收通道本振来源映射表
|
||||||
|
*/
|
||||||
|
static const std::map<std::pair<LoSource, LoSource>, std::bitset<7>> rxSrcMap = {
|
||||||
|
{ { LoSource::Pll2, LoSource::Pll2 }, 0b0010000 }, { { LoSource::Pll1, LoSource::Pll1 }, 0b1101000 },
|
||||||
|
{ { LoSource::Pll2, LoSource::Pll1 }, 0b0100000 }, { { LoSource::Pll1, LoSource::Pll2 }, 0b1000000 },
|
||||||
|
{ { LoSource::Off, LoSource::Pll1 }, 0b0101010 }, { { LoSource::Off, LoSource::Pll2 }, 0b1010010 },
|
||||||
|
{ { LoSource::Pll1, LoSource::Off }, 0b1001001 }, { { LoSource::Pll2, LoSource::Off }, 0b0110001 },
|
||||||
|
{ { LoSource::Off, LoSource::Off }, 0b0011011 }
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* @brief 发射通道本振来源映射表
|
||||||
|
*/
|
||||||
|
static const std::map<std::pair<LoSource, LoSource>, std::bitset<11>> txSrcMap = {
|
||||||
|
{ { LoSource::Pll4, LoSource::Pll4 }, 16 }, { { LoSource::Pll3, LoSource::Pll3 }, 104 },
|
||||||
|
{ { LoSource::Pll4, LoSource::Pll3 }, 32 }, { { LoSource::Pll3, LoSource::Pll4 }, 64 },
|
||||||
|
{ { LoSource::Pll2, LoSource::Pll2 }, 1560 }, { { LoSource::Pll1, LoSource::Pll1 }, 1944 },
|
||||||
|
{ { LoSource::Pll2, LoSource::Pll1 }, 1688 }, { { LoSource::Pll1, LoSource::Pll2 }, 1816 },
|
||||||
|
{ { LoSource::Off, LoSource::Pll3 }, 42 }, { { LoSource::Off, LoSource::Pll4 }, 82 },
|
||||||
|
{ { LoSource::Off, LoSource::Pll2 }, 794 }, { { LoSource::Off, LoSource::Pll1 }, 666 },
|
||||||
|
{ { LoSource::Pll3, LoSource::Off }, 73 }, { { LoSource::Pll4, LoSource::Off }, 49 },
|
||||||
|
{ { LoSource::Pll2, LoSource::Off }, 1177 }, { { LoSource::Pll1, LoSource::Off }, 1305 },
|
||||||
|
{ { LoSource::Off, LoSource::Off }, 27 }, { { LoSource::Pll1, LoSource::Pll3 }, 1320 },
|
||||||
|
{ { LoSource::Pll1, LoSource::Pll4 }, 1360 }, { { LoSource::Pll2, LoSource::Pll3 }, 1064 },
|
||||||
|
{ { LoSource::Pll2, LoSource::Pll4 }, 1104 }, { { LoSource::Pll3, LoSource::Pll1 }, 712 },
|
||||||
|
{ { LoSource::Pll4, LoSource::Pll1 }, 688 }, { { LoSource::Pll3, LoSource::Pll2 }, 584 },
|
||||||
|
{ { LoSource::Pll4, LoSource::Pll2 }, 560 }
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* @brief 环路参数选择表
|
||||||
|
*/
|
||||||
|
static const std::vector<std::vector<std::vector<int>>> coreTable = {
|
||||||
|
{ { 0x0C, 0x30, 0x08 }, { 0x0B, 0x30, 0x09 }, { 0x0C, 0x30, 0x05 }, { 0x0D, 0x30, 0x08 } },
|
||||||
|
{ { 0x0C, 0x30, 0x0C }, { 0x0B, 0x30, 0x0E }, { 0x0C, 0x30, 0x08 }, { 0x0D, 0x30, 0x0B } },
|
||||||
|
{ { 0x0C, 0x20, 0x10 }, { 0x0B, 0x20, 0x10 }, { 0x0C, 0x20, 0x0A }, { 0x0D, 0x20, 0x0D } },
|
||||||
|
{ { 0x0C, 0x20, 0x11 }, { 0x0B, 0x20, 0x13 }, { 0x0C, 0x20, 0x0C }, { 0x0D, 0x20, 0x0F } },
|
||||||
|
{ { 0x0D, 0x30, 0x14 }, { 0x0D, 0x22, 0x14 }, { 0x0D, 0x20, 0x0D }, { 0x0D, 0x15, 0x0C } },
|
||||||
|
{ { 0x0E, 0x30, 0x18 }, { 0x0E, 0x25, 0x16 }, { 0x0E, 0x25, 0x0F }, { 0x0E, 0x18, 0x0F } },
|
||||||
|
{ { 0x0F, 0x38, 0x1A }, { 0x0F, 0x32, 0x1C }, { 0x0F, 0x18, 0x12 }, { 0x0F, 0x18, 0x12 } }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AGC PDT模式的结构体
|
||||||
|
*/
|
||||||
|
struct AGCPDT
|
||||||
|
{
|
||||||
|
int pdtN;
|
||||||
|
int pdtM;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AGC LMT模式的结构体
|
||||||
|
*/
|
||||||
|
struct AGCLMT
|
||||||
|
{
|
||||||
|
int count; /**< LMT统计次数阈值*/
|
||||||
|
int threshold1; /**< LMT阈值第一档*/
|
||||||
|
int threshold2; /**< LMT阈值第二档*/
|
||||||
|
int threshold3; /**< LMT阈值第三档*/
|
||||||
|
int threshold4; /**< LMT阈值第四档*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AGC DIG模式的结构体
|
||||||
|
*/
|
||||||
|
struct AGCDIG
|
||||||
|
{
|
||||||
|
int count; /**< DIG统计次数阈值*/
|
||||||
|
int threshold1; /**< DIG阈值第一档*/
|
||||||
|
int threshold2; /**< DIG阈值第二档*/
|
||||||
|
int threshold3; /**< DIG阈值第三档*/
|
||||||
|
int threshold4; /**< DIG阈值第四档*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AGC模式的结构体
|
||||||
|
*/
|
||||||
|
struct AGC
|
||||||
|
{
|
||||||
|
int mode; /**< AGC模式选择*/
|
||||||
|
AGCPDT pdt; /**< AGC PDT模式的结构体*/
|
||||||
|
AGCLMT lmt; /**< AGC LMT模式的结构体*/
|
||||||
|
AGCDIG dig; /**< AGC DIG模式的结构体*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 时钟相关参数结构体
|
||||||
|
*/
|
||||||
|
struct Clock
|
||||||
|
{
|
||||||
|
double ref; /**< 参考时钟频率,单位MHz*/
|
||||||
|
double adc; /**< ADC频率,单位MHz*/
|
||||||
|
int refDiv; /**< 参考时钟分频比*/
|
||||||
|
bool bbUseIntDiv; /**< 是否使用整数分频模式*/
|
||||||
|
bool refDoubler; /**< 是否使用参考时钟倍频器*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 校准相关参数结构体
|
||||||
|
*/
|
||||||
|
struct Calib
|
||||||
|
{
|
||||||
|
bool calibDC; /**< 是否开启DC Tracking*/
|
||||||
|
DCCalibMethod dcCalibMethod;
|
||||||
|
int dcTrackingLength; /**< DC Tracking长度*/
|
||||||
|
int dcHighPassFactor; /**< DC高通滤波系数,越大代表滤波器阶数越高,滤波范围越窄*/
|
||||||
|
std::uint8_t rx1CalibPll; /**< rx1校准的pll选择,Pll1 | Pll2*/
|
||||||
|
std::uint8_t rx2CalibPll; /**< rx2校准的pll选择,Pll1 | Pll2*/
|
||||||
|
std::uint8_t rx3CalibPll; /**< rx3校准的pll选择,Pll5*/
|
||||||
|
std::uint8_t tx1CalibPll; /**< tx1校准的pll选择,Pll1 | Pll2 | Pll3 | Pll4*/
|
||||||
|
std::uint8_t tx2CalibPll; /**< tx2校准的pll选择,Pll1 | Pll2 | Pll3 | Pll4*/
|
||||||
|
CalibMethod rxMethod;
|
||||||
|
CalibMethod txMethod;
|
||||||
|
double f0; /**< 校准音频率*/
|
||||||
|
std::vector<double> rxMultiPoints; /**< Rx多点校准的频率*/
|
||||||
|
std::vector<double> txMultiPoints; /**< Tx多点校准的频率*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 配置PLL来源相关参数结构体
|
||||||
|
*/
|
||||||
|
struct PllSource
|
||||||
|
{
|
||||||
|
bool rxUseExt; /**< 接收通道是否使用外本振*/
|
||||||
|
bool txUseExt; /**< 发射通道是否使用外本振*/
|
||||||
|
LoSource rx1Source; /**< Rx1通道本振来源*/
|
||||||
|
LoSource rx2Source; /**< Rx2通道本振来源*/
|
||||||
|
LoSource rx3Source; /**< Rx3通道本振来源*/
|
||||||
|
LoSource tx1Source; /**< Tx1通道本振来源*/
|
||||||
|
LoSource tx2Source; /**< Tx2通道本振来源*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 配置PLL频率相关参数结构体
|
||||||
|
*/
|
||||||
|
struct PllFreq
|
||||||
|
{
|
||||||
|
double pll1Freq; /**< PLL1本振时钟,单位MHz*/
|
||||||
|
double pll2Freq; /**< PLL2本振时钟,单位MHz*/
|
||||||
|
double pll3Freq; /**< PLL3本振时钟,单位MHz*/
|
||||||
|
double pll4Freq; /**< PLL4本振时钟,单位MHz*/
|
||||||
|
double pll5Freq; /**< PLL5本振时钟,单位MHz*/
|
||||||
|
double rxExtFreq; /**< 接收通道使用外本振时,外本振频率,单位MHz*/
|
||||||
|
double txExtFreq; /**< 发射通道使用外本振时,外本振频率,单位MHz*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 配置接口相关参数结构体
|
||||||
|
*/
|
||||||
|
struct Interface
|
||||||
|
{
|
||||||
|
WorkMode workMode; /**< 芯片工作模式*/
|
||||||
|
TrMode trMode; /**< 收发数据通道模式*/
|
||||||
|
PortMode portMode; /**< 收发接口通道模式*/
|
||||||
|
IOMode ioMode; /**< 接口电平模式*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 配置TX NCO相关参数结构体
|
||||||
|
*/
|
||||||
|
struct TxNCO
|
||||||
|
{
|
||||||
|
bool txUseBist; /**< 是否开启BIST模式*/
|
||||||
|
double txNCOFreq; /**< NCO频率*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 配置RX NCO相关参数结构体
|
||||||
|
*/
|
||||||
|
struct RxNCO
|
||||||
|
{
|
||||||
|
bool rxUseBist; /**< 是否开启BIST模式*/
|
||||||
|
bool rxNCOBypass; /**< 是否Bypass NCO*/
|
||||||
|
bool rxNCOUpward; /**< 开启上/下混频模式*/
|
||||||
|
bool rxNCOMaster; /**< 使用Master/Slaver模式*/
|
||||||
|
double rxNCOFreq; /**< NCO频率*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 配置接收通道相关参数结构体
|
||||||
|
*/
|
||||||
|
struct RxConfig
|
||||||
|
{
|
||||||
|
double bandwidth; /**< 接收通道1dB带宽,单位MHz*/
|
||||||
|
int tia; /**< 接收通道TIA增益配置,推荐配置6*/
|
||||||
|
int mixer; /**< 接收通道Mixer增益配置*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 配置发射通道相关参数结构体
|
||||||
|
*/
|
||||||
|
struct TxConfig
|
||||||
|
{
|
||||||
|
double bandwidth; /**< 发射通道1dB带宽,单位MHz*/
|
||||||
|
int mixer; /**< 发射通道Mixer增益配置*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 配置滤波器相关参数结构体,0代表bypass
|
||||||
|
*/
|
||||||
|
struct Filters
|
||||||
|
{
|
||||||
|
int fir; /**< FIR滤波器抽取/插值倍数*/
|
||||||
|
int hbf1; /**< HBF1滤波器抽取/插值倍数*/
|
||||||
|
int hbf2; /**< HBF2滤波器抽取/插值倍数*/
|
||||||
|
int hbf3; /**< HBF3滤波器抽取/插值倍数*/
|
||||||
|
int cic; /**< CIC滤波器抽取/插值倍数*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 配置电源模式结构体,1代表该模块上电
|
||||||
|
*/
|
||||||
|
struct Power
|
||||||
|
{
|
||||||
|
bool dig_tx2;
|
||||||
|
bool dig_tx1;
|
||||||
|
bool dig_rx3;
|
||||||
|
bool dig_rx2;
|
||||||
|
bool dig_rx1;
|
||||||
|
bool fref1_rx;
|
||||||
|
bool auxadc2;
|
||||||
|
bool auxadc1;
|
||||||
|
bool auxdac;
|
||||||
|
bool temp_sensor;
|
||||||
|
bool bgr;
|
||||||
|
bool exlo;
|
||||||
|
bool tx2;
|
||||||
|
bool tx1;
|
||||||
|
bool rx3;
|
||||||
|
bool rx2;
|
||||||
|
bool rx1;
|
||||||
|
bool pll5_ldo;
|
||||||
|
bool pll5;
|
||||||
|
bool pll4_ldo;
|
||||||
|
bool pll4;
|
||||||
|
bool pll3_ldo;
|
||||||
|
bool pll3;
|
||||||
|
bool pll2_ldo;
|
||||||
|
bool pll2;
|
||||||
|
bool pll1_ldo;
|
||||||
|
bool pll1;
|
||||||
|
bool bbpll;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 配置电源模式管理,包含模式选择,接收模式,发射模式,FDD模式
|
||||||
|
*/
|
||||||
|
struct PowerManagement
|
||||||
|
{
|
||||||
|
PowerMode powerMode;
|
||||||
|
Power rxPower;
|
||||||
|
Power txPower;
|
||||||
|
Power fddPower;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 储存窄带校准结果的结构体
|
||||||
|
*/
|
||||||
|
struct CalibPredis
|
||||||
|
{
|
||||||
|
int bHigh;
|
||||||
|
int bLow;
|
||||||
|
int cHigh;
|
||||||
|
int cLow;
|
||||||
|
int dciHigh;
|
||||||
|
int dciLow;
|
||||||
|
int dcqHigh;
|
||||||
|
int dcqLow;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CX9261A结构体
|
||||||
|
*/
|
||||||
|
struct CX9261AConfiguration
|
||||||
|
{
|
||||||
|
TemperatureComp tempComp; /**< 温度补偿*/
|
||||||
|
AGC agc; /**< AGC结构体*/
|
||||||
|
Interface interface; /**< Interface结构体*/
|
||||||
|
Clock clock; /**< Clock结构体*/
|
||||||
|
PllSource pllSource; /**< PllSource结构体*/
|
||||||
|
Calib calib; /**< Calib结构体*/
|
||||||
|
PllFreq pllFreq; /**< PllFreq结构体*/
|
||||||
|
TxNCO txNco; /**< TxNCO结构体*/
|
||||||
|
RxNCO rxNco; /**< RxNCO结构体*/
|
||||||
|
RxConfig rx1Config; /**< RxConfig结构体*/
|
||||||
|
RxConfig rx2Config; /**< RxConfig结构体*/
|
||||||
|
RxConfig rx3Config; /**< RxConfig结构体*/
|
||||||
|
TxConfig tx1Config; /**< TxConfig结构体*/
|
||||||
|
TxConfig tx2Config; /**< TxConfig结构体*/
|
||||||
|
Filters rxFilters; /**< Filters结构体*/
|
||||||
|
Filters txFilters; /**< Filters结构体*/
|
||||||
|
PowerManagement powerManagement; /**< PowerManagement结构体*/
|
||||||
|
std::vector<double> rxFIRCoe; /**< Rx FIR滤波器系数*/
|
||||||
|
std::vector<double> txFIRCoe; /**< Tx FIR滤波器系数*/
|
||||||
|
};
|
||||||
|
} // namespace CX9261A
|
||||||
|
#endif // CX9261ADRIVER_DEFS_H
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
#include "cx9261adriver.h"
|
||||||
|
#include "defs.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
// 芯片配置结构体
|
||||||
|
CX9261A::CX9261AConfiguration configuration;
|
||||||
|
// 电源管理
|
||||||
|
// 接收模式电源管理
|
||||||
|
configuration.powerManagement.rxPower = {0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0,
|
||||||
|
0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1};
|
||||||
|
// 发射模式电源管理
|
||||||
|
configuration.powerManagement.txPower = {1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1};
|
||||||
|
// FDD模式电源管理
|
||||||
|
configuration.powerManagement.fddPower = {1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1,
|
||||||
|
0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1};
|
||||||
|
// 电源模式 即配置结束后的电源模式
|
||||||
|
configuration.powerManagement.powerMode = CX9261A::PowerMode::Receive;
|
||||||
|
// 接口模式
|
||||||
|
configuration.interface = {.workMode = CX9261A::WorkMode::Rx,
|
||||||
|
.trMode = CX9261A::TrMode::R1T1,
|
||||||
|
.portMode = CX9261A::PortMode::Single,
|
||||||
|
.ioMode = CX9261A::IOMode::CMOS};
|
||||||
|
// 时钟相关
|
||||||
|
configuration.clock = {.ref = 125, .adc = 64, .refDiv = 2, .bbUseIntDiv = false, .refDoubler = false};
|
||||||
|
// 本振相关
|
||||||
|
using LoSource = CX9261A::LoSource;
|
||||||
|
// 本振来源
|
||||||
|
configuration.pllSource = {.rxUseExt = false,
|
||||||
|
.txUseExt = false,
|
||||||
|
.rx1Source = LoSource::Pll1,
|
||||||
|
.rx2Source = LoSource::Pll1,
|
||||||
|
.rx3Source = LoSource::Off,
|
||||||
|
.tx1Source = LoSource::Off,
|
||||||
|
.tx2Source = LoSource::Off};
|
||||||
|
// 本振频率 注意:使用的所有PLL,频率必须设为正数
|
||||||
|
configuration.pllFreq = {
|
||||||
|
.pll1Freq = 5800, .pll2Freq = 5800, .pll3Freq = 800, .pll4Freq = 900, .pll5Freq = 1000};
|
||||||
|
// Rx通道 注意:tia推荐配置为6 Mixer为三个通道共用同一个寄存器
|
||||||
|
configuration.rx1Config = {.bandwidth = 32, .tia = 6, .mixer = 31};
|
||||||
|
configuration.rx2Config = {.bandwidth = 32, .tia = 6, .mixer = 31};
|
||||||
|
configuration.rx3Config = {.bandwidth = 32, .tia = 6, .mixer = 31};
|
||||||
|
// Tx通道
|
||||||
|
configuration.tx1Config = {.bandwidth = 20, .mixer = 63};
|
||||||
|
configuration.tx2Config = {.bandwidth = 20, .mixer = 63};
|
||||||
|
// 接收滤波器
|
||||||
|
configuration.rxFilters = {.fir = 0, .hbf1 = 0, .hbf2 = 0, .hbf3 = 0, .cic = 0};
|
||||||
|
// 发射滤波器
|
||||||
|
configuration.txFilters = {.fir = 0, .hbf1 = 2, .hbf2 = 2, .hbf3 = 0, .cic = 0};
|
||||||
|
// Rx NCO
|
||||||
|
configuration.rxNco = {
|
||||||
|
.rxUseBist = false, .rxNCOBypass = true, .rxNCOUpward = true, .rxNCOMaster = true, .rxNCOFreq = 0};
|
||||||
|
// Tx NCO
|
||||||
|
configuration.txNco = {.txUseBist = false, .txNCOFreq = 0};
|
||||||
|
// AGC 注意:mode = 0表示关闭AGC,此时其他的参数可以不配置
|
||||||
|
configuration.calib = {
|
||||||
|
.calibDC = true,
|
||||||
|
.dcCalibMethod = CX9261A::DCCalibMethod::Tracking,
|
||||||
|
.dcTrackingLength = 16384,
|
||||||
|
.dcHighPassFactor = 8191,
|
||||||
|
.rx1CalibPll = int(LoSource::Pll1) | int(LoSource::Pll2),
|
||||||
|
.rx2CalibPll = int(LoSource::Pll1) | int(LoSource::Pll2),
|
||||||
|
.rx3CalibPll = int(LoSource::Pll5),
|
||||||
|
.tx1CalibPll = 0,
|
||||||
|
.tx2CalibPll = 0,
|
||||||
|
.rxMethod = CX9261A::CalibMethod::MultiPoints,
|
||||||
|
.txMethod = CX9261A::CalibMethod::Bisec,
|
||||||
|
.f0 = 4
|
||||||
|
};
|
||||||
|
configuration.agc = {.mode = 0};
|
||||||
|
// 校准
|
||||||
|
configuration.calib.rxMultiPoints = {2200, 2400, 2600, 2800, 3000, 3200, 3400, 3600, 3800, 4000, 4200,
|
||||||
|
4400, 4600, 4800, 5000, 5200, 5400, 5600, 5800, 6000};
|
||||||
|
// 配置温补模式为跳子带温补
|
||||||
|
configuration.tempComp = CX9261A::TemperatureComp::Band;
|
||||||
|
|
||||||
|
// 开始配置芯片
|
||||||
|
CX9261A::initialChip(); // 最开始需要调用此函数
|
||||||
|
CX9261A::initialPowerConfig(configuration);
|
||||||
|
// 配置温补
|
||||||
|
configTemperatureCompensation(configuration.tempComp);
|
||||||
|
using PowerMode = CX9261A::PowerMode;
|
||||||
|
// 不需要自定义电源管理时,这部分代码可以省略
|
||||||
|
CX9261A::configPowerPins(configuration.powerManagement.rxPower, PowerMode::Receive);
|
||||||
|
CX9261A::configPowerPins(configuration.powerManagement.txPower, PowerMode::Transmit);
|
||||||
|
CX9261A::configPowerPins(configuration.powerManagement.fddPower, PowerMode::Duplex);
|
||||||
|
// 配置pll
|
||||||
|
CX9261A::configBBPLL(configuration);
|
||||||
|
CX9261A::configPllSource(configuration.pllSource);
|
||||||
|
CX9261A::configPll1(configuration.pllFreq.pll1Freq, configuration.clock);
|
||||||
|
CX9261A::configPll2(configuration.pllFreq.pll2Freq, configuration.clock);
|
||||||
|
// 配置Rx通道
|
||||||
|
CX9261A::configRxChannel(configuration.rx1Config, CX9261A::RxChannel::Rx1);
|
||||||
|
CX9261A::configRxChannel(configuration.rx2Config, CX9261A::RxChannel::Rx2);
|
||||||
|
CX9261A::configRxChannel(configuration.rx3Config, CX9261A::RxChannel::Rx3);
|
||||||
|
// 配置Tx通道
|
||||||
|
using TxChannel = CX9261A::TxChannel;
|
||||||
|
CX9261A::configTxChannelFrequency(configuration.pllFreq.pll1Freq, TxChannel::Tx1);
|
||||||
|
CX9261A::configTxChannelFrequency(configuration.pllFreq.pll2Freq, TxChannel::Tx2);
|
||||||
|
CX9261A::configTxChannel(configuration.tx1Config, TxChannel::Tx1);
|
||||||
|
CX9261A::configTxChannel(configuration.tx2Config, TxChannel::Tx2);
|
||||||
|
// 配置滤波器
|
||||||
|
CX9261A::configRxFilters(configuration.rxFilters);
|
||||||
|
CX9261A::configTxFilters(configuration.txFilters);
|
||||||
|
// 配置NCO
|
||||||
|
CX9261A::configRxNco(configuration.rxNco, configuration.clock.adc);
|
||||||
|
const int filters = std::max(configuration.rxFilters.fir, 1) * std::max(configuration.rxFilters.hbf3, 1) *
|
||||||
|
std::max(configuration.rxFilters.hbf2, 1) *
|
||||||
|
std::max(configuration.rxFilters.hbf1, 1) * std::max(configuration.rxFilters.cic, 1);
|
||||||
|
CX9261A::configTxNco(configuration.txNco, configuration.clock.adc / filters);
|
||||||
|
// 配置AGC
|
||||||
|
CX9261A::configAGC(configuration.agc);
|
||||||
|
// 切换到休眠模式
|
||||||
|
CX9261A::configPowerMode(PowerMode::Sleep);
|
||||||
|
CX9261A::pause(1000);
|
||||||
|
// 切换到校准模式
|
||||||
|
CX9261A::configPowerMode(PowerMode::Calib);
|
||||||
|
CX9261A::pause(100);
|
||||||
|
// 锁定BBPLL
|
||||||
|
CX9261A::afcBBPll();
|
||||||
|
// 配置校准
|
||||||
|
CX9261A::configADCCalib(configuration.clock.adc);
|
||||||
|
CX9261A::configFlashCalib();
|
||||||
|
configDcCalib(configuration.calib);
|
||||||
|
configQecCalib(configuration);
|
||||||
|
CX9261A::loadRxCalibPredis(0, CX9261A::RxChannel::Rx1, LoSource::Pll1);
|
||||||
|
CX9261A::loadRxCalibPredis(0, CX9261A::RxChannel::Rx2, LoSource::Pll1);
|
||||||
|
// 配置接口
|
||||||
|
CX9261A::configInterface(configuration.interface);
|
||||||
|
// 配置FPGA接口相关 此为示例,仅适用于Demo工程,用户应根据实际情况进行配置
|
||||||
|
CX9261A::configFPGA(configuration.interface);
|
||||||
|
// 锁定PLL1
|
||||||
|
CX9261A::afcPll1();
|
||||||
|
// 锁定PLL2
|
||||||
|
CX9261A::afcPll2();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
/**
|
||||||
|
* @file utils.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CX9261ADRIVER_UTILS_H
|
||||||
|
#define CX9261ADRIVER_UTILS_H
|
||||||
|
#include <algorithm>
|
||||||
|
#include <bitset>
|
||||||
|
#include <cmath>
|
||||||
|
#include <string>
|
||||||
|
namespace CX9261A {
|
||||||
|
#if __cplusplus >= 201703L
|
||||||
|
template <typename T>
|
||||||
|
constexpr const T& clamp(const T& v, const T& lo, const T& hi) {
|
||||||
|
return std::clamp(v, lo, hi);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template <typename T>
|
||||||
|
constexpr const T& clamp(const T& v, const T& lo, const T& hi) {
|
||||||
|
return std::max(std::min(hi, v), lo);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <typename Float>
|
||||||
|
int round(Float f) {
|
||||||
|
return static_cast<int>(std::round(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Float>
|
||||||
|
long long round64(Float f) {
|
||||||
|
return static_cast<long long>(std::round(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Float>
|
||||||
|
int floor(Float f) {
|
||||||
|
return static_cast<int>(std::floor(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Float>
|
||||||
|
long long floor64(Float f) {
|
||||||
|
return static_cast<long long>(std::floor(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Float>
|
||||||
|
int ceil(Float f) {
|
||||||
|
return static_cast<int>(std::ceil(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Float>
|
||||||
|
long long ceil64(Float f) {
|
||||||
|
return static_cast<long long>(std::ceil(f));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief Register类,提供方便的位操作函数
|
||||||
|
*/
|
||||||
|
class Register {
|
||||||
|
public:
|
||||||
|
template <typename T = int>
|
||||||
|
constexpr Register(const T value = 0) {
|
||||||
|
static_assert(std::is_integral_v<T>, "Register value must be integral!");
|
||||||
|
m_value = static_cast<unsigned long long>(value);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 以十进制返回寄存器值
|
||||||
|
*/
|
||||||
|
unsigned char value() const { return static_cast<unsigned char>(m_value.to_ulong()); }
|
||||||
|
/**
|
||||||
|
* 对寄存器值进行部分值的替换操作
|
||||||
|
* 例:replace(7, 4, 0b1111); 使寄存器的高四位为1
|
||||||
|
* @param start 起始位
|
||||||
|
* @param end 中止位
|
||||||
|
* @param after 要替换的值
|
||||||
|
*/
|
||||||
|
void replace(const unsigned int start, const unsigned int end, unsigned char after) {
|
||||||
|
for (auto i = end; i <= start; ++i) {
|
||||||
|
m_value[i] = (after >> (i - end)) & 0b1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto operator[](const size_t position) { return m_value[position]; }
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
operator Type() const {
|
||||||
|
static_assert(std::is_integral_v<Type>, "Type must be an integral");
|
||||||
|
return static_cast<Type>(m_value.to_ulong());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::bitset<8> m_value{};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <int N>
|
||||||
|
std::string frac2bin(const double frac) {
|
||||||
|
const long double num = frac * (pow(2.0, N));
|
||||||
|
std::string ret = std::bitset<N>(std::floor(num)).to_string();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} // namespace CX9261A
|
||||||
|
#endif // CX9261ADRIVER_UTILS_H
|
||||||
Reference in New Issue
Block a user