feat: 新增工程,由20241025技术支持包中的coms工程upgrade得到,发端修改为演示验证QPSK
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
# keep compiled libs
|
||||
!*.a
|
||||
|
||||
# Buid folder
|
||||
build/
|
||||
|
||||
# Xilinx tools generated files
|
||||
.metadata/
|
||||
.settings/
|
||||
.wsdata/
|
||||
.Xil/
|
||||
logs/
|
||||
Packages/
|
||||
*.log*
|
||||
|
||||
# System generated files
|
||||
# -- macOS
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
._*
|
||||
|
||||
# -- Windows
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
Desktop.ini
|
||||
|
||||
# -- Linux
|
||||
*~
|
||||
|
||||
# IDEs and editors' files
|
||||
*.idea
|
||||
*.vscode
|
||||
*.sublime-workspace
|
||||
*.sublime-project
|
||||
@@ -0,0 +1,8 @@
|
||||
include ../../scripts/generic_variables.mk
|
||||
|
||||
PLATFORM := xilinx
|
||||
CONFIG_FILE := $(PROJECT)/config.json
|
||||
XILINX_VITIS_CLASSIC = y
|
||||
SCRIPT_DIR = ../../scripts
|
||||
|
||||
include ../../scripts/generic.mk
|
||||
@@ -0,0 +1,32 @@
|
||||
@echo off
|
||||
set "platform=xilinx"
|
||||
set "pltform_ver=2024.1"
|
||||
set "work_dir=%~dp0build"
|
||||
set "config=%~dp0config.json"
|
||||
set "tools_dir=%~dp0..\..\scripts\platform\%platform%"
|
||||
|
||||
REM Set up enviroment
|
||||
call "%tools_dir%\setenv.bat" "%pltform_ver%"
|
||||
if "%ERRORLEVEL%" neq "0" (
|
||||
echo Error: Failed to installize enviroment.
|
||||
pause >nul
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM Build project
|
||||
call "%tools_dir%\build.bat" "%config%" "%work_dir%"
|
||||
if "%ERRORLEVEL%" neq "0" (
|
||||
echo Error: Failed to build project.
|
||||
pause >nul
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM Lauch SDK
|
||||
call "%tools_dir%\launch.bat" "%pltform_ver%" "%work_dir%"
|
||||
if "%ERRORLEVEL%" neq "0" (
|
||||
echo Error: Failed to launch SDK.
|
||||
pause >nul
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
exit /b 0
|
||||
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"project_name": "cx9261a_demo_cmos_20240829",
|
||||
"version": "20240829",
|
||||
"hw_design": "../CX9261A_ZC706.xsa",
|
||||
"hw_version": "20241102",
|
||||
"apps": {
|
||||
"cx9261a_api_app": {
|
||||
"sources": ["source_cx9261a_api_1_10_0/"],
|
||||
"target_cpu": "ps7_cortexa9_0",
|
||||
"os": "standalone",
|
||||
"language": "C++",
|
||||
"mem_layout" : {
|
||||
"heap_size": "0x80000",
|
||||
"stack_size": "0x4000"
|
||||
}
|
||||
},
|
||||
"CX9261A_CPPV4": {
|
||||
"sources": ["source_CX9261A_CPPV4/"],
|
||||
"target_cpu": "ps7_cortexa9_0",
|
||||
"os": "standalone",
|
||||
"language": "C++",
|
||||
"mem_layout" : {
|
||||
"heap_size": "0x80000",
|
||||
"stack_size": "0x4000"
|
||||
}
|
||||
},
|
||||
"CX9261A_HOP": {
|
||||
"sources": ["source_CX9261A_HOP/"],
|
||||
"target_cpu": "ps7_cortexa9_0",
|
||||
"os": "freertos10_xilinx",
|
||||
"language": "C",
|
||||
"mem_layout" : {
|
||||
"heap_size": "0x80000",
|
||||
"stack_size": "0x4000"
|
||||
},
|
||||
"bsp_lib": {
|
||||
"lwip220": {
|
||||
"version": "1.0",
|
||||
"config": {
|
||||
"api_mode": "SOCKET_API",
|
||||
"pbuf_pool_size": 2048
|
||||
}
|
||||
},
|
||||
"xilffs": {
|
||||
"version": "5.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ddr_test": {
|
||||
"sources": ["source_ddr_test/"],
|
||||
"target_cpu": "ps7_cortexa9_0",
|
||||
"os": "standalone",
|
||||
"language": "C++",
|
||||
"mem_layout" : {
|
||||
"heap_size": "0x80000",
|
||||
"stack_size": "0x4000"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2186
File diff suppressed because it is too large
Load Diff
+546
@@ -0,0 +1,546 @@
|
||||
/**
|
||||
* @file cx9261adriver.h
|
||||
*/
|
||||
|
||||
#ifndef CX9261ADRIVER_CX9261ADRIVER_H
|
||||
#define CX9261ADRIVER_CX9261ADRIVER_H
|
||||
|
||||
#define VERSION 1.10.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
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* download_bin.c
|
||||
*
|
||||
* Created on: 2023年11月23日
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
#include "xilinx_io.h"
|
||||
#include "sleep.h"
|
||||
void download_bin(void){
|
||||
|
||||
int temp;
|
||||
u8 rx_data;
|
||||
u8 data[4];
|
||||
u32 buf;
|
||||
u8 addr[2];
|
||||
int dpd_multicalib = 0;// 1:dpd,0:multicalib
|
||||
if (dpd_multicalib) {
|
||||
SpiPs_write_read1(0x079,0x00,&rx_data);//关闭CRC校验
|
||||
SpiPs_write_read1(0x071,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x071,0x09,&rx_data);
|
||||
for(int i=0;i<5507;i++){
|
||||
addr[0]=(i>>8)&0xff;
|
||||
addr[1]= i&0xff;
|
||||
buf=rom_read((u8 *)&addr);
|
||||
data[0]=buf>>24;
|
||||
data[1]=(buf>>16)&0xff;
|
||||
data[2]=(buf>>8)&0xff;
|
||||
data[3]=buf&0xff;
|
||||
for(int j=0;j<4;j++){
|
||||
SpiPs_write_read1(0x070,data[j],&rx_data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SpiPs_write_read1(0x071,0x1A,&rx_data);//开启CRC校验
|
||||
SpiPs_write_read1(0x079,0x08,&rx_data);//开启CRC校验
|
||||
usleep(1000);
|
||||
SpiPs_write_read2(0x078,0x00,&rx_data);
|
||||
temp=rx_data;
|
||||
|
||||
if (temp == 0x01) {
|
||||
xil_printf("CRC successful");
|
||||
}
|
||||
else {
|
||||
xil_printf("CRC unsuccessful");
|
||||
}
|
||||
SpiPs_write_read1(0x071,0x06,&rx_data);//处理器门控时钟使能
|
||||
usleep(10000);
|
||||
SpiPs_write_read2(0x0A7,0x00,&rx_data);//处理器运行成果标志
|
||||
temp=rx_data;
|
||||
|
||||
if (temp == 0x11) {
|
||||
xil_printf("core run successful");
|
||||
}
|
||||
else {
|
||||
xil_printf("core run unsuccessful");
|
||||
}
|
||||
////////////////////dpd系数加载////////////////////
|
||||
SpiPs_write_read1(0x302,0xDF,&rx_data);
|
||||
SpiPs_write_read1(0x0A3,0x52,&rx_data);
|
||||
usleep(200000);
|
||||
SpiPs_write_read2(0x0A7,0x00,&rx_data);//dpd系数加载完成标志
|
||||
temp=rx_data;
|
||||
|
||||
if (temp == 0x61) {
|
||||
xil_printf("dpd index load bin successful");
|
||||
}
|
||||
else {
|
||||
xil_printf("dpd index load bin unsuccessful");
|
||||
}
|
||||
}
|
||||
else {
|
||||
SpiPs_write_read1(0x071,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x071,0x29,&rx_data);
|
||||
for(int i=0;i<15379;i++){
|
||||
addr[0]=(i>>8)&0xff;
|
||||
addr[1]= i&0xff;
|
||||
buf=rom_read((u8 *)&addr);
|
||||
data[0]=buf>>24;
|
||||
data[1]=(buf>>16)&0xff;
|
||||
data[2]=(buf>>8)&0xff;
|
||||
data[3]=buf&0xff;
|
||||
for(int j=0;j<4;j++){
|
||||
SpiPs_write_read1(0x070,data[j],&rx_data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SpiPs_write_read1(0x071,0x26,&rx_data);
|
||||
SpiPs_write_read1(0x02E,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
//验证是否下载成功
|
||||
SpiPs_write_read2(0x0AB,0x00,&rx_data);
|
||||
temp=rx_data;
|
||||
|
||||
if (temp == 0x08) {
|
||||
xil_printf("multicalib load bin successful");
|
||||
}
|
||||
else {
|
||||
xil_printf("multicalib load bin unsuccessful");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* frqhop_config.c
|
||||
*
|
||||
* Created on: 2023年11月24日
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
#include "xilinx_io.h"
|
||||
#include "sleep.h"
|
||||
#include "time.h"
|
||||
#include "xtime_l.h"
|
||||
#include "math.h"
|
||||
#include "cx9261adriver.h"
|
||||
|
||||
CX9261A::Clock* ref_clock;
|
||||
|
||||
void trx_ch_pll_config(u8 pll_index);
|
||||
|
||||
void frqhop_config(int hop_flag){
|
||||
static XTime tCur;
|
||||
XTime_GetTime(&tCur);
|
||||
srand(tCur);
|
||||
static double hop_freq ;
|
||||
hop_freq = (rand()%(800-30))+30+(rand()%(101))/(double)100;//随机产生[30,800)double类型的数
|
||||
// double hop_freq = 400.52;
|
||||
static double hop_freq1 = 800.25;
|
||||
static int pll_index=1;
|
||||
static int unlock_pll1_cnt=0,unlock_pll2_cnt=0;
|
||||
if(hop_freq == hop_freq1){
|
||||
if(pll_index == 2){
|
||||
pll_index = 4;
|
||||
}
|
||||
else if(pll_index == 1){
|
||||
pll_index = 3;
|
||||
}
|
||||
}
|
||||
if(hop_flag == 1){
|
||||
if(pll_index == 1 || pll_index == 3)
|
||||
{
|
||||
//切换至pll2来源
|
||||
trx_ch_pll_config(2);
|
||||
//配置pll1参数
|
||||
CX9261A::configPll1(hop_freq,*ref_clock);
|
||||
while (!CX9261A::afcPll1()) {
|
||||
unlock_pll1_cnt++;
|
||||
}
|
||||
pll_index = 2;
|
||||
}
|
||||
else if(pll_index == 2 || pll_index == 4)
|
||||
{
|
||||
//切换至pll1来源
|
||||
trx_ch_pll_config(1);
|
||||
//配置pll2参数
|
||||
CX9261A::configPll2(hop_freq,*ref_clock);
|
||||
while (!CX9261A::afcPll2()) {
|
||||
unlock_pll2_cnt++;
|
||||
}
|
||||
pll_index = 1;
|
||||
}
|
||||
else if(pll_index == 3 )
|
||||
{
|
||||
//切换至pll2来源
|
||||
trx_ch_pll_config(2);
|
||||
pll_index = 2;
|
||||
}
|
||||
else if(pll_index == 4 ){
|
||||
//切换至pll1来源
|
||||
trx_ch_pll_config(1);
|
||||
pll_index = 1;
|
||||
}
|
||||
}
|
||||
hop_freq1 = hop_freq;
|
||||
if(unlock_pll2_cnt!=0 || unlock_pll1_cnt !=0){
|
||||
xil_printf("pll1 unlock num: %d; pll2 unlock num: %d;.\n", unlock_pll1_cnt, unlock_pll2_cnt);
|
||||
}
|
||||
}
|
||||
|
||||
void trx_ch_pll_config(u8 pll_index)
|
||||
{
|
||||
u8 rx_data;
|
||||
u8 recv_buf[3]={0};
|
||||
u32 trx_ch_pll_data;
|
||||
|
||||
if(pll_index==1){
|
||||
trx_ch_pll_data = 0x00077DCF;
|
||||
}else if(pll_index==2){
|
||||
trx_ch_pll_data = 0x00077D0C;
|
||||
}
|
||||
|
||||
recv_buf[0] =(trx_ch_pll_data>>16 & 0xff)|0x80 ;
|
||||
recv_buf[1] = trx_ch_pll_data>>8 & 0xff;
|
||||
recv_buf[2] = trx_ch_pll_data & 0xff;
|
||||
SpiPs_write_read(recv_buf,&rx_data);
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
#include "cx9261adriver.h"
|
||||
#include "defs.h"
|
||||
#include "utils.h"
|
||||
#include "xilinx_io.h"
|
||||
|
||||
|
||||
int main() {
|
||||
SpiPsInit(SPI_DEVICE_ID);
|
||||
GpioInit(GPIO_DEVICE_ID);
|
||||
/* cx9261a configuration */
|
||||
peripheral_test();
|
||||
download_bin();//多频点校准CX9261A处理器执行文件
|
||||
AXIGpioInit();
|
||||
XScuGicInit();
|
||||
ConfigAXIGPIOIntr();
|
||||
ExceptionInit();
|
||||
|
||||
/***********************配置参数定义*****************************/
|
||||
// 芯片配置结构体
|
||||
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::Transmit;
|
||||
// 接口模式
|
||||
configuration.interface.workMode = CX9261A::WorkMode::Tx;
|
||||
configuration.interface.trMode = CX9261A::TrMode::R1T1;
|
||||
configuration.interface.portMode = CX9261A::PortMode::Single;
|
||||
configuration.interface.ioMode = CX9261A::IOMode::CMOS;
|
||||
// 时钟相关 (与评估软件参考配置和基带配置相对应)
|
||||
configuration.clock.ref = 100;
|
||||
configuration.clock .adc = 50;
|
||||
configuration.clock .refDiv = 1;
|
||||
configuration.clock .bbUseIntDiv = false;
|
||||
configuration.clock .refDoubler = false;
|
||||
// 本振相关
|
||||
using LoSource = CX9261A::LoSource;
|
||||
// 本振来源
|
||||
configuration.pllSource.rxUseExt = false;
|
||||
configuration.pllSource.txUseExt = false;
|
||||
configuration.pllSource.rx1Source = LoSource::Pll1;
|
||||
configuration.pllSource.rx2Source = LoSource::Pll1;
|
||||
configuration.pllSource.rx3Source = LoSource::Off;
|
||||
configuration.pllSource.tx1Source = LoSource::Pll1;
|
||||
configuration.pllSource.tx2Source = LoSource::Pll1;
|
||||
// 本振频率 注意:使用的所有PLL,频率必须设为正数
|
||||
configuration.pllFreq.pll1Freq = 800;
|
||||
configuration.pllFreq.pll2Freq = 5800;
|
||||
configuration.pllFreq.pll3Freq = 800;
|
||||
configuration.pllFreq.pll4Freq = 900;
|
||||
configuration.pllFreq.pll5Freq = 1000;
|
||||
// Rx通道 注意:tia推荐配置为6 Mixer为三个通道共用同一个寄存器
|
||||
configuration.rx1Config.bandwidth = 32;
|
||||
configuration.rx1Config.tia = 6;
|
||||
configuration.rx1Config.mixer = 31;
|
||||
configuration.rx2Config.bandwidth = 32;
|
||||
configuration.rx2Config.tia = 6;
|
||||
configuration.rx2Config.mixer = 31;
|
||||
configuration.rx3Config.bandwidth = 32;
|
||||
configuration.rx3Config.tia = 6;
|
||||
configuration.rx3Config.mixer = 31;
|
||||
// Tx通道
|
||||
configuration.tx1Config.bandwidth = 20;
|
||||
configuration.tx1Config.mixer = 63;
|
||||
configuration.tx2Config.bandwidth = 20;
|
||||
configuration.tx2Config.mixer = 63;
|
||||
// 接收滤波器
|
||||
configuration.rxFilters.fir = 0;
|
||||
configuration.rxFilters.hbf1 = 0;
|
||||
configuration.rxFilters.hbf2 = 0;
|
||||
configuration.rxFilters.hbf3 = 0;
|
||||
configuration.rxFilters.cic = 0;
|
||||
// 发射滤波器
|
||||
configuration.txFilters.fir = 0;
|
||||
configuration.txFilters.hbf1 = 2;
|
||||
configuration.txFilters.hbf2 = 2;
|
||||
configuration.txFilters.hbf3 = 0;
|
||||
configuration.txFilters.cic = 0;
|
||||
// Rx NCO
|
||||
configuration.rxNco.rxUseBist = false;
|
||||
configuration.rxNco.rxNCOBypass = true;
|
||||
configuration.rxNco.rxNCOUpward = true;
|
||||
configuration.rxNco.rxNCOMaster = true;
|
||||
configuration.rxNco.rxNCOFreq = 0;
|
||||
// Tx NCO
|
||||
configuration.txNco.txUseBist = true;
|
||||
configuration.txNco.txNCOFreq = 1;
|
||||
// AGC 注意:mode = 0表示关闭AGC,此时其他的参数可以不配置
|
||||
configuration.agc.mode = 0;
|
||||
configuration.agc.pdt.pdtN = 0;
|
||||
configuration.agc.pdt.pdtM = 2;
|
||||
configuration.agc.lmt.count = 15;
|
||||
configuration.agc.lmt.threshold1 = 2;
|
||||
configuration.agc.lmt.threshold2 = 2;
|
||||
configuration.agc.lmt.threshold3 = 2;
|
||||
configuration.agc.lmt.threshold4 = 2;
|
||||
configuration.agc.dig.count = 15;
|
||||
configuration.agc.dig.threshold1 =-10;
|
||||
configuration.agc.dig.threshold2 =-14;
|
||||
configuration.agc.dig.threshold3 =-30;
|
||||
configuration.agc.dig.threshold4 =-40;
|
||||
// 校准
|
||||
//跳频qec校准频点预设,最多256个频点。其中包含初始频点则加载初始频点校准值给三个通道
|
||||
configuration.calib.calibDC = true;
|
||||
configuration.calib.dcCalibMethod = CX9261A::DCCalibMethod::Tracking;
|
||||
configuration.calib.dcTrackingLength = 16384;
|
||||
configuration.calib.dcHighPassFactor = 8191;
|
||||
configuration.calib.rx1CalibPll = int(LoSource::Pll1);
|
||||
configuration.calib.rx2CalibPll = int(LoSource::Pll1);
|
||||
configuration.calib.rx3CalibPll = false;
|
||||
configuration.calib.tx1CalibPll = int(LoSource::Pll1);
|
||||
configuration.calib.tx2CalibPll = int(LoSource::Pll1);
|
||||
configuration.calib.rxMethod = CX9261A::CalibMethod::TST;
|
||||
configuration.calib.rxMultiPoints = {2000, 5600, 5800, 6000};
|
||||
configuration.calib.txMethod = CX9261A::CalibMethod::Bisec;
|
||||
configuration.calib.txMultiPoints = {3500, 5600, 5800, 6000};
|
||||
configuration.calib.f0 = 5;
|
||||
|
||||
// 配置温补模式为跳子带温补
|
||||
configuration.tempComp = CX9261A::TemperatureComp::Band;
|
||||
|
||||
ref_clock = &configuration.clock;
|
||||
/***********************配置参数执行*****************************/
|
||||
// 开始配置芯片
|
||||
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);
|
||||
// CX9261A::configPll3(configuration.pllFreq.pll3Freq, configuration.clock);
|
||||
// CX9261A::configPll4(configuration.pllFreq.pll4Freq, 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.pll1Freq, 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
|
||||
while (!CX9261A::afcBBPll()) {
|
||||
}
|
||||
// 配置接口
|
||||
CX9261A::configInterface(configuration.interface);
|
||||
// 配置FPGA接口相关 此为示例,仅适用于Demo工程,用户应根据实际情况进行配置
|
||||
CX9261A::configFPGA(configuration.interface);
|
||||
// 配置校准
|
||||
CX9261A::configDcCalib(configuration.calib);
|
||||
CX9261A::configADCCalib(configuration.clock.adc);
|
||||
CX9261A::configFlashCalib();
|
||||
CX9261A::configQecCalib(configuration);
|
||||
// CX9261A::loadRxCalibPredis(0, CX9261A::RxChannel::Rx1, LoSource::Pll1);
|
||||
// CX9261A::loadRxCalibPredis(0, CX9261A::RxChannel::Rx2, LoSource::Pll2);
|
||||
// 切换到工作模式
|
||||
CX9261A::configPowerMode(configuration.powerManagement.powerMode);
|
||||
// 锁定PLL 根据本振来源确定是否需要AFC
|
||||
CX9261A::afcPll1();
|
||||
|
||||
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
|
||||
@@ -0,0 +1,313 @@
|
||||
/*
|
||||
* xilinx_io.cc
|
||||
*
|
||||
* Created on: 2024年3月5日
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
#include "sleep.h"
|
||||
#include "math.h"
|
||||
#include "xilinx_io.h" /* SPI device driver */
|
||||
#include "cx9261adriver.h"
|
||||
#include "utils.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static XSpiPs SpiInstance;
|
||||
XGpioPs Gpio; /* The driver instance for GPIO Device. */
|
||||
XGpio axi_gpio_inst; //PL 端 AXI GPIO 驱动实例
|
||||
XScuGic scugic_inst; //中断控制器 驱动实例
|
||||
XScuGic_Config * scugic_cfg_ptr; //中断控制器 配置信息
|
||||
int hop_flag,hop_intr_flag;
|
||||
static int spi_select_value=0;
|
||||
|
||||
//跳频中断初始化
|
||||
void AXIGpioInit(void){
|
||||
XGpio_Initialize(&axi_gpio_inst, AXI_GPIO_ID);
|
||||
//配置 PL AXI GPIO
|
||||
XGpio_SetDataDirection(&axi_gpio_inst, 1, 1); //设置 AXI GPIO 通道 1 为输入
|
||||
XGpio_InterruptEnable(&axi_gpio_inst, FRQHOP_MASK); //使能通道 1 中断
|
||||
XGpio_InterruptGlobalEnable(&axi_gpio_inst); //使能 AXI GPIO 全局中断
|
||||
}
|
||||
void ConfigAXIGPIOIntr(void){
|
||||
//设置中断优先级和触发类型(高电平触发)
|
||||
XScuGic_SetPriorityTriggerType(&scugic_inst, GPIO_INT_ID, 0xA0, 0x3);
|
||||
//关联中断 ID 和中断处理函数
|
||||
XScuGic_Connect(&scugic_inst, GPIO_INT_ID, axi_gpio_handler, &axi_gpio_inst);
|
||||
//使能 AXI GPIO 中断
|
||||
XScuGic_Enable(&scugic_inst, GPIO_INT_ID);
|
||||
}
|
||||
void axi_gpio_handler(void *CallbackRef){
|
||||
XGpio *GpioPtr = (XGpio *)CallbackRef;
|
||||
GpioWritePin(hop,0x01);
|
||||
XGpio_InterruptDisable(GpioPtr, FRQHOP_MASK); //关闭 AXI GPIO 中断使能
|
||||
frqhop_config(hop_flag);
|
||||
XGpio_InterruptClear(GpioPtr, FRQHOP_MASK); //清除中断
|
||||
XGpio_InterruptEnable(GpioPtr, FRQHOP_MASK); //使能 AXI GPIO 中断
|
||||
GpioWritePin(hop,0x00);
|
||||
}
|
||||
void ExceptionInit(void){
|
||||
//设置并打开中断异常处理功能
|
||||
Xil_ExceptionInit();
|
||||
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, &scugic_inst);
|
||||
Xil_ExceptionEnable();
|
||||
}
|
||||
void XScuGicInit(void){
|
||||
scugic_cfg_ptr = XScuGic_LookupConfig(SCUGIC_ID);
|
||||
XScuGic_CfgInitialize(&scugic_inst, scugic_cfg_ptr, scugic_cfg_ptr->CpuBaseAddress);
|
||||
}
|
||||
void frqhop_flag(int frqhop_flag){
|
||||
u8 rx_data;
|
||||
hop_flag = frqhop_flag;
|
||||
GpioWritePin(hop,0x01);
|
||||
SpiPs_write_read2(0x615,0x00,&rx_data);
|
||||
GpioWritePin(hop,0x00);
|
||||
}
|
||||
|
||||
//ps spi(emio)初始化
|
||||
int SpiPsInit(u16 SpiDeviceId){
|
||||
int Status;
|
||||
XSpiPs_Config *SpiConfig;
|
||||
/*
|
||||
* Initialize the SPI driver so that it's ready to use
|
||||
*/
|
||||
SpiConfig = XSpiPs_LookupConfig(SpiDeviceId);
|
||||
if (NULL == SpiConfig) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
Status = XSpiPs_CfgInitialize((&SpiInstance), SpiConfig,
|
||||
SpiConfig->BaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a self-test to check hardware build
|
||||
*/
|
||||
Status = XSpiPs_SelfTest((&SpiInstance));
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
/*
|
||||
* The SPI device is a slave by default and the clock phase
|
||||
* have to be set according to its master. In this example, CPOL is set
|
||||
* to quiescent high and CPHA is set to 1.
|
||||
*/
|
||||
|
||||
XSpiPs_SetOptions((&SpiInstance), (XSPIPS_CR_CPHA_MASK) |
|
||||
XSPIPS_MASTER_OPTION |
|
||||
XSPIPS_FORCE_SSELECT_OPTION);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
XSpiPs_SetClkPrescaler((&SpiInstance), XSPIPS_CLK_PRESCALE_8);
|
||||
/*
|
||||
* Set the Rx FIFO Threshold to the Max Data
|
||||
*/
|
||||
// XSpiPs_SetRXWatermark((&SpiInstance),MAX_DATA);
|
||||
/*
|
||||
* Enable the device.
|
||||
*/
|
||||
XSpiPs_Enable((&SpiInstance));
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
//gpio(emio)初始化
|
||||
int GpioInit(u16 DeviceId)
|
||||
{
|
||||
int Status;
|
||||
XGpioPs_Config *ConfigPtr;
|
||||
/* Initialize the GPIO driver. */
|
||||
ConfigPtr = XGpioPs_LookupConfig(DeviceId);
|
||||
Status = XGpioPs_CfgInitialize(&Gpio, ConfigPtr,
|
||||
ConfigPtr->BaseAddr);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
int GpioSetPinDir(u32 Pin,u32 Direction){
|
||||
XGpioPs_SetDirectionPin((&Gpio),GPIO_EMIO_OFFSET + Pin,Direction);
|
||||
return 0;
|
||||
}
|
||||
int GpioWritePin(u32 Pin,u32 data){
|
||||
GpioSetPinDir(Pin,GPIO_DIR_OUTPUT);
|
||||
XGpioPs_SetOutputEnablePin(&Gpio, GPIO_EMIO_OFFSET + Pin, 1);
|
||||
XGpioPs_WritePin((&Gpio),GPIO_EMIO_OFFSET + Pin,data);
|
||||
return 0;
|
||||
}
|
||||
int GpioReadPin(u32 Pin){
|
||||
GpioSetPinDir(Pin,GPIO_DIR_INPUT);
|
||||
return XGpioPs_ReadPin((&Gpio),GPIO_EMIO_OFFSET + Pin);
|
||||
}
|
||||
|
||||
//外设测试及相关复位
|
||||
int peripheral_test(void){
|
||||
u8 spi_test;
|
||||
u8 BRAM_test;
|
||||
u8 DDR_test;
|
||||
|
||||
// CX9261A 复位
|
||||
GpioWritePin(NRST,0x00);
|
||||
GpioWritePin(NRST,0x01);
|
||||
// CX9261A接口驱动 复位
|
||||
GpioWritePin(rst,0x01);
|
||||
GpioWritePin(rst,0x00);
|
||||
// CX9261A接收数据fifo 复位
|
||||
GpioWritePin(aresetn_0,0x00);
|
||||
GpioWritePin(aresetn_0,0x01);
|
||||
GpioWritePin(aresetn_1,0x00);
|
||||
GpioWritePin(aresetn_1,0x01);
|
||||
GpioWritePin(aresetn_2,0x00);
|
||||
GpioWritePin(aresetn_2,0x01);
|
||||
// CX3E04 复位
|
||||
GpioWritePin(cx3e04_rstn,0x00);
|
||||
GpioWritePin(cx3e04_rstn,0x01);
|
||||
// CX9261A spi选择 0:ps spi(emio);1:axi pl spi
|
||||
GpioWritePin(spi_select,spi_select_value&0xff);
|
||||
|
||||
// SPI TEST
|
||||
u8 rx_data;
|
||||
xil_printf("start spi test.\r\n");
|
||||
u8 spi_wr_buff[3]={0x87,0x82,0x5A};
|
||||
u8 spi_rd_buff[3]={0x07,0x82,0x00};
|
||||
SpiPs_write_read(spi_wr_buff,&rx_data);
|
||||
SpiPs_write_read(spi_rd_buff,&rx_data);
|
||||
if(rx_data==spi_wr_buff[2])
|
||||
{
|
||||
xil_printf("spi test successful.\r\n");
|
||||
spi_test = 1;
|
||||
}else
|
||||
{
|
||||
xil_printf("spi test unsuccessful.\r\n");
|
||||
spi_test = 0;
|
||||
}
|
||||
//BRAM TEST
|
||||
xil_printf("start bram test.\r\n");
|
||||
BRAM_test = 1;
|
||||
for (u32 i=0;i<8192;i++){
|
||||
Xil_Out32(XPAR_BRAM_0_BASEADDR + 4*i,i);
|
||||
u32 bram0_data= Xil_In32(XPAR_BRAM_0_BASEADDR + 4*i);
|
||||
Xil_Out32(XPAR_BRAM_1_BASEADDR + 4*i,i);
|
||||
u32 bram1_data= Xil_In32(XPAR_BRAM_1_BASEADDR + 4*i);
|
||||
if(i != bram0_data)
|
||||
{
|
||||
xil_printf("BRAM0 ERROR,ADDR %x DATA %d read back is %d.\r\n",XPAR_BRAM_0_BASEADDR + 4*i,i,bram0_data);
|
||||
BRAM_test = 0;
|
||||
}
|
||||
if(i != bram1_data)
|
||||
{
|
||||
xil_printf("BRAM1 ERROR,ADDR %x DATA %d read back is %d.\r\n",XPAR_BRAM_1_BASEADDR + 4*i,i,bram1_data);
|
||||
BRAM_test = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//MIG TEST
|
||||
xil_printf("start mig test.\r\n");
|
||||
DDR_test = 1;
|
||||
for (u32 i=0;i<2048;i++){
|
||||
Xil_Out32(TX_BUFFER_BASE + 4*i,i);
|
||||
u32 ddr_data= Xil_In32(TX_BUFFER_BASE + 4*i);
|
||||
if(i != ddr_data)
|
||||
{
|
||||
xil_printf("MIG ERROR,ADDR %x DATA %d read back is %d.\r\n",TX_BUFFER_BASE + 4*i,i,ddr_data);
|
||||
DDR_test = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if((spi_test==1)&&(BRAM_test==1)&&(DDR_test==1))
|
||||
{
|
||||
xil_printf("peripheral test successful.\r\n");
|
||||
return 1;
|
||||
}else
|
||||
{
|
||||
xil_printf("peripheral test unsuccessful.\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//axi总线结合pl spi模块实现cx9261a spi读写
|
||||
int cx9261a_write(int addr , int value)
|
||||
{
|
||||
Xil_Out32(AXI4_LITE1_SPI_BASEADDR+addr*4,value);
|
||||
return 1;
|
||||
}
|
||||
int cx9261a_read(int addr)
|
||||
{
|
||||
return Xil_In32(AXI4_LITE1_SPI_BASEADDR+addr*4);
|
||||
}
|
||||
//ps spi(emio)实现cx9261a spi读写
|
||||
int SpiPs_write_read(u8 * data,u8 * rx_data){
|
||||
int Status;
|
||||
u8 rx_buffer[3];
|
||||
|
||||
if(spi_select_value == 0){
|
||||
rx_buffer[0]= *data;
|
||||
rx_buffer[1]= *(data+1);
|
||||
rx_buffer[2]= *(data+2);
|
||||
if(rx_buffer[0] >= 128){
|
||||
cx9261a_write((rx_buffer[0]-128)*256+rx_buffer[1],rx_buffer[2]);
|
||||
}else{
|
||||
*rx_data=cx9261a_read(rx_buffer[0]*256+rx_buffer[1]);
|
||||
}
|
||||
}else{
|
||||
|
||||
XSpiPs_SetSlaveSelect((&SpiInstance),0x00);
|
||||
|
||||
Status = XSpiPs_PolledTransfer((&SpiInstance),data,rx_buffer,3);
|
||||
|
||||
*rx_data = rx_buffer[2];
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int SpiPs_write_read1(u16 addr,u8 data,u8 * rx_data){
|
||||
u8 rx_data1;
|
||||
u16 temp;
|
||||
u8 rx_buffer[3];
|
||||
|
||||
temp= addr&0xff00;
|
||||
rx_buffer[0]= temp/256+SPI_WRITE;
|
||||
rx_buffer[1]= addr&0x00ff;
|
||||
rx_buffer[2]= data;
|
||||
|
||||
if(spi_select_value == 0){
|
||||
cx9261a_write(addr,data);
|
||||
}else{
|
||||
|
||||
SpiPs_write_read((u8 *)&rx_buffer,&rx_data1);
|
||||
*rx_data = rx_data1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int SpiPs_write_read2(u16 addr,u8 data,u8 * rx_data){
|
||||
u8 rx_data1;
|
||||
u16 temp;
|
||||
u8 rx_buffer[3];
|
||||
|
||||
temp= addr&0xff00;
|
||||
rx_buffer[0]= temp/256+SPI_READ;
|
||||
rx_buffer[1]= addr&0x00ff;
|
||||
rx_buffer[2]= data;
|
||||
|
||||
if(spi_select_value == 0){
|
||||
*rx_data=cx9261a_read(addr);
|
||||
}else{
|
||||
SpiPs_write_read((u8 *)&rx_buffer,&rx_data1);
|
||||
*rx_data = rx_data1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//axi读取pl rom
|
||||
int rom_read(u8 * data)
|
||||
{
|
||||
int addr ;
|
||||
addr = *(data + 0)*256+ *(data + 1);
|
||||
return Xil_In32(BROM_BASEADDR+addr*4);
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* xilinx_io.h
|
||||
*
|
||||
* Created on: 2021年9月6日
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
#ifndef SRC_XILINX_IO_H_
|
||||
#define SRC_XILINX_IO_H_
|
||||
|
||||
|
||||
#endif /* SRC_XILINX_IO_H_ */
|
||||
#include "xspips.h" /* SPI device driver */
|
||||
#include "xgpiops.h"
|
||||
#include "xgpio.h"
|
||||
#include "xparameters.h"
|
||||
#include "xscugic.h"
|
||||
#include "xil_exception.h"
|
||||
#include "defs.h"
|
||||
|
||||
extern CX9261A::Clock* ref_clock;
|
||||
|
||||
#define SPI_WRITE 0x80
|
||||
#define SPI_READ 0x00
|
||||
#define GPIO_DIR_INPUT 0x00
|
||||
#define GPIO_DIR_OUTPUT 0x01
|
||||
#define GPIO_EMIO_OFFSET 54
|
||||
|
||||
#define NRST 0
|
||||
#define ENABLE_TRX1 1
|
||||
#define ENABLE_TRX2 2
|
||||
#define ENABLE_TRX3 3
|
||||
#define TXNRX_TRX1 4
|
||||
#define TXNRX_TRX2 5
|
||||
#define TXNRX_RX3 6
|
||||
|
||||
#define aresetn_0 33
|
||||
#define rst 34
|
||||
#define tr_sel 35
|
||||
#define tdd_fdd_sel 36
|
||||
#define r1t1_r2t2_sel 37
|
||||
#define sp_dp_sel 38
|
||||
#define aresetn_1 39
|
||||
#define aresetn_2 40
|
||||
#define hop 41
|
||||
#define cx3e04_rstn 42
|
||||
#define spi_select 46
|
||||
|
||||
|
||||
#define SPI_DEVICE_ID XPAR_XQSPIPS_0_DEVICE_ID
|
||||
#define GPIO_DEVICE_ID XPAR_PS7_GPIO_0_DEVICE_ID
|
||||
|
||||
#define BROM_BASEADDR XPAR_M08_AXI_0_BASEADDR
|
||||
|
||||
#define AXI4_LITE0_SPI_BASEADDR XPAR_AXI4_LITE_SPI_0_BASEADDR
|
||||
#define AXI4_LITE1_SPI_BASEADDR XPAR_AXI4_LITE_SPI_1_BASEADDR
|
||||
|
||||
#define TX_BUFFER_BASE XPAR_MIG_7SERIES_0_BASEADDR +0x2000
|
||||
|
||||
|
||||
#define GPIO_INT_ID XPAR_FABRIC_GPIO_0_VEC_ID //PL 端 AXI GPIO 中断 ID
|
||||
#define AXI_GPIO_ID XPAR_AXI_GPIO_0_DEVICE_ID //PL 端 AXI GPIO 器件 ID
|
||||
#define SCUGIC_ID XPAR_SCUGIC_0_DEVICE_ID //中断控制器 ID
|
||||
|
||||
#define FRQHOP_MASK XGPIO_IR_CH1_MASK //通道 1 的位定义
|
||||
|
||||
void AXIGpioInit(void);
|
||||
void ConfigAXIGPIOIntr(void);
|
||||
void axi_gpio_handler(void *CallbackRef);
|
||||
void XScuGicInit(void);
|
||||
void ExceptionInit(void);
|
||||
void frqhop_flag(int frqhop_flag);
|
||||
|
||||
int SpiPsInit(u16 SpiDeviceId);
|
||||
|
||||
int GpioInit(u16 DeviceId);
|
||||
int GpioSetPinDir(u32 Pin,u32 Direction);
|
||||
int GpioWritePin(u32 Pin,u32 data);
|
||||
int GpioReadPin(u32 Pin);
|
||||
|
||||
int peripheral_test(void);
|
||||
|
||||
//cx3e04和cx9261a初始化配置及读写寄存器函数
|
||||
//void cx3e04_config(void);
|
||||
//int cx3e04_write(int addr , int value);
|
||||
//int cx3e04_read(int addr);
|
||||
int cx9261a_write(int addr , int value);
|
||||
int cx9261a_read(int addr);
|
||||
int SpiPs_write_read(u8 * data,u8 * rx_data);
|
||||
int SpiPs_write_read1(u16 addr,u8 data,u8 * rx_data);
|
||||
int SpiPs_write_read2(u16 addr,u8 data,u8 * rx_data);
|
||||
|
||||
//跳频
|
||||
void frqhop_config(int hop_flag);
|
||||
void trx_ch_pll_config(u8 pll_index);
|
||||
|
||||
//PL rom读取和cx9261a bin文件下载
|
||||
int rom_read(u8 * data);
|
||||
void download_bin(void);
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* download_bin.c
|
||||
*
|
||||
* Created on: 2023年11月23日
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
#include "xilinx_io.h"
|
||||
#include "sleep.h"
|
||||
void download_bin(void){
|
||||
|
||||
int temp;
|
||||
u8 rx_data;
|
||||
u8 data[4];
|
||||
u32 buf;
|
||||
u8 addr[2];
|
||||
int dpd_multicalib = 0;// 1:dpd,0:multicalib
|
||||
if (dpd_multicalib) {
|
||||
SpiPs_write_read1(0x079,0x00,&rx_data);//关闭CRC校验
|
||||
SpiPs_write_read1(0x071,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x071,0x09,&rx_data);
|
||||
for(int i=0;i<5507;i++){
|
||||
addr[0]=(i>>8)&0xff;
|
||||
addr[1]= i&0xff;
|
||||
buf=rom_read((u8 *)&addr);
|
||||
data[0]=buf>>24;
|
||||
data[1]=(buf>>16)&0xff;
|
||||
data[2]=(buf>>8)&0xff;
|
||||
data[3]=buf&0xff;
|
||||
for(int j=0;j<4;j++){
|
||||
SpiPs_write_read1(0x070,data[j],&rx_data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SpiPs_write_read1(0x071,0x1A,&rx_data);//开启CRC校验
|
||||
SpiPs_write_read1(0x079,0x08,&rx_data);//开启CRC校验
|
||||
usleep(1000);
|
||||
SpiPs_write_read2(0x078,0x00,&rx_data);
|
||||
temp=rx_data;
|
||||
|
||||
if (temp == 0x01) {
|
||||
xil_printf("CRC successful");
|
||||
}
|
||||
else {
|
||||
xil_printf("CRC unsuccessful");
|
||||
}
|
||||
SpiPs_write_read1(0x071,0x06,&rx_data);//处理器门控时钟使能
|
||||
usleep(10000);
|
||||
SpiPs_write_read2(0x0A7,0x00,&rx_data);//处理器运行成果标志
|
||||
temp=rx_data;
|
||||
|
||||
if (temp == 0x11) {
|
||||
xil_printf("core run successful");
|
||||
}
|
||||
else {
|
||||
xil_printf("core run unsuccessful");
|
||||
}
|
||||
////////////////////dpd系数加载////////////////////
|
||||
SpiPs_write_read1(0x302,0xDF,&rx_data);
|
||||
SpiPs_write_read1(0x0A3,0x52,&rx_data);
|
||||
usleep(200000);
|
||||
SpiPs_write_read2(0x0A7,0x00,&rx_data);//dpd系数加载完成标志
|
||||
temp=rx_data;
|
||||
|
||||
if (temp == 0x61) {
|
||||
xil_printf("dpd index load bin successful");
|
||||
}
|
||||
else {
|
||||
xil_printf("dpd index load bin unsuccessful");
|
||||
}
|
||||
}
|
||||
else {
|
||||
SpiPs_write_read1(0x071,0x00,&rx_data);
|
||||
SpiPs_write_read1(0x071,0x29,&rx_data);
|
||||
for(int i=0;i<15379;i++){
|
||||
addr[0]=(i>>8)&0xff;
|
||||
addr[1]= i&0xff;
|
||||
buf=rom_read((u8 *)&addr);
|
||||
data[0]=buf>>24;
|
||||
data[1]=(buf>>16)&0xff;
|
||||
data[2]=(buf>>8)&0xff;
|
||||
data[3]=buf&0xff;
|
||||
for(int j=0;j<4;j++){
|
||||
SpiPs_write_read1(0x070,data[j],&rx_data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SpiPs_write_read1(0x071,0x26,&rx_data);
|
||||
SpiPs_write_read1(0x02E,0x03,&rx_data);
|
||||
usleep(100000);
|
||||
//验证是否下载成功
|
||||
SpiPs_write_read2(0x0AB,0x00,&rx_data);
|
||||
temp=rx_data;
|
||||
|
||||
if (temp == 0x08) {
|
||||
xil_printf("multicalib load bin successful");
|
||||
}
|
||||
else {
|
||||
xil_printf("multicalib load bin unsuccessful");
|
||||
}
|
||||
SpiPs_write_read1(0x02E,0x00,&rx_data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,436 @@
|
||||
/*
|
||||
* Copyright (C) 2016 - 2018 Xilinx, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lwip/sockets.h"
|
||||
#include "netif/xadapter.h"
|
||||
#include "lwipopts.h"
|
||||
#include "xil_printf.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "xilinx_io.h"
|
||||
|
||||
#define THREAD_STACKSIZE 1024
|
||||
#define ACK 0x01
|
||||
u16_t echo_port = 7;
|
||||
//#define RECV_BUF_SIZE 65536*16*8
|
||||
#define RECV_BUF_SIZE 1024
|
||||
//char recv_buf[RECV_BUF_SIZE];
|
||||
char recv_buf[1024];
|
||||
char recv_buf_temp[3];
|
||||
char trans_buf[8192*5];
|
||||
struct spi_stack spistack;
|
||||
|
||||
|
||||
u16 hop_cnt = 0;
|
||||
|
||||
void print_echo_app_header()
|
||||
{
|
||||
xil_printf("%20s %6d %s\r\n", "echo server",
|
||||
echo_port,
|
||||
"$ telnet <board_ip> 7");
|
||||
|
||||
}
|
||||
|
||||
|
||||
enum {
|
||||
CMD_VER = 0,
|
||||
CMD_RST = 1,
|
||||
CMD_SPI_WRI = 2 ,
|
||||
CMD_SPI_READ = 3,
|
||||
CMD_DATA_CAPTURE0 = 4,
|
||||
CMD_WAVE_DOWNLOAD = 5,
|
||||
CMD_PIN_SET = 6,
|
||||
CMD_DATA_CAPTURE1 = 8,
|
||||
CMD_DATA_CAPTURE2 = 9,
|
||||
CMD_STACK_OUT = 10,
|
||||
CMD_hopping = 11,
|
||||
CMD_qecbin = 12,
|
||||
CMD_cx9261a_config = 13,
|
||||
CMD_cx3e04_config = 14,
|
||||
CMD_cx3e04_SPI_WRI = 15 ,
|
||||
CMD_cx3e04_SPI_READ = 16,
|
||||
CMD_IMAGE_UPDATE = 22,
|
||||
};
|
||||
/* thread spawned for each connection */
|
||||
void process_echo_request(void *p)
|
||||
{
|
||||
int sd = (int)p;
|
||||
int status;
|
||||
int n, nwrote,send_n,total_send;
|
||||
u8 rx_data;
|
||||
u32 capture_length;
|
||||
u8 pin;
|
||||
u8 pin_value;
|
||||
char FPGA_SDK_IP[]="FPGA:2024829-SDK:202400829";
|
||||
spistack.spi_write_num = 0;
|
||||
while (1) {
|
||||
/* read a max of RECV_BUF_SIZE bytes from socket */
|
||||
if ((n = read(sd, recv_buf, 5)) < 0) {
|
||||
xil_printf("%s: error reading from socket %d, closing socket\r\n", __FUNCTION__, sd);
|
||||
break;
|
||||
}
|
||||
|
||||
/* break if the recved message = "quit" */
|
||||
if (!strncmp(recv_buf, "quit", 4))
|
||||
break;
|
||||
|
||||
/* break if client closed connection */
|
||||
if (n <= 0)
|
||||
break;
|
||||
|
||||
else{/* excute cmd if recved message = "cmd"*/
|
||||
n=0;
|
||||
if (!strncmp(recv_buf, "cmd ", 4)){
|
||||
// xil_printf("%d %d %d %d.\r\n", recv_buf[0],recv_buf[1],recv_buf[2],recv_buf[4]);
|
||||
dbg_printf("Rece %d bytes.\r\n",n);
|
||||
switch(recv_buf[4]){
|
||||
case CMD_IMAGE_UPDATE:
|
||||
{
|
||||
|
||||
u32 offset;
|
||||
u32 image_size;
|
||||
recv_buf[0] = ACK;
|
||||
nwrote = write(sd, recv_buf, 1);
|
||||
n = read(sd, recv_buf, RECV_BUF_SIZE);
|
||||
|
||||
offset = *(u32 *)recv_buf;
|
||||
image_size = *(u32 *)(recv_buf + 4);
|
||||
xil_printf("offset is 0x%x image_size is 0x%x.\n", offset, image_size);
|
||||
|
||||
void *image_ptr = (void *)0x30000000;
|
||||
u32 LengthBytes;
|
||||
write(sd, recv_buf, 1); // ask for image data
|
||||
//// receive flash image to ddr
|
||||
LengthBytes = 0;
|
||||
while (LengthBytes < image_size)
|
||||
{
|
||||
n = read(sd, image_ptr + LengthBytes, RECV_BUF_SIZE);
|
||||
// xil_printf("read %d bytes.\n",n);
|
||||
LengthBytes = LengthBytes + n;
|
||||
}
|
||||
|
||||
// image data sumcheck
|
||||
|
||||
// program image data into flash
|
||||
//QspiStore( (u32) image_ptr, offset, image_size);
|
||||
//xil_printf("flash program done.\n", n);
|
||||
status = FfsSdWrite(image_ptr, image_size);
|
||||
write(sd, recv_buf, 1); // send done
|
||||
xil_printf("sd program done.\n", n);
|
||||
n = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case CMD_VER:
|
||||
dbg_printf("Version:FPGA_20240829;SDK_20240829;IP_192.168.1.99.\r\n");
|
||||
n=26;
|
||||
for(int i=0;i<26;i++){
|
||||
recv_buf[i] = FPGA_SDK_IP[i];
|
||||
}
|
||||
break;
|
||||
case CMD_RST:
|
||||
dbg_printf("Rece cmd excute rst.\r\n");
|
||||
DeviceRst();
|
||||
break;
|
||||
|
||||
case CMD_STACK_OUT:
|
||||
dbg_printf("Rece cmd STACK OUT.\r\n");
|
||||
spi_stack_out(&spistack);
|
||||
n=1;
|
||||
recv_buf[0] = 0x55;
|
||||
break;
|
||||
case CMD_SPI_WRI:
|
||||
read(sd, &recv_buf[5], 3);//´ÓsocketÖжÁ3¸ö×Ö·û·ÅÔÚrecv_buf[5:7]ÖÐ
|
||||
dbg_printf("Rece cmd excute spi write.\r\n");
|
||||
dbg_printf("ADDR 0x%x DATA 0x%x.\r\n",recv_buf[5]*256+recv_buf[6]-32768,recv_buf[7]);
|
||||
// SpiPs_write_read((u8 *)&recv_buf[5],&rx_data);
|
||||
status = spi_stack_in((u8 *)&recv_buf[5],&spistack);
|
||||
if(status){//when memory is near full,start spi write
|
||||
spi_stack_out(&spistack);
|
||||
}
|
||||
// n=1;
|
||||
// recv_buf[0] = rx_data;
|
||||
break;
|
||||
case CMD_SPI_READ:
|
||||
read(sd, &recv_buf[5], 3);
|
||||
dbg_printf("Rece cmd excute spi read.\r\n");
|
||||
dbg_printf("ADDR 0x%x DATA 0x%x.\r\n",recv_buf[5]*256+recv_buf[6],recv_buf[7]);
|
||||
SpiPs_write_read((u8 *)&recv_buf[5],&rx_data);
|
||||
n=1;
|
||||
recv_buf[0] = rx_data;
|
||||
break;
|
||||
case CMD_DATA_CAPTURE0:
|
||||
read(sd, &recv_buf[5], 4);
|
||||
capture_length = *((u32 *) &recv_buf[5]);//num of sample
|
||||
dbg_printf("Rece cmd excute %d sample data capture.\r\n",capture_length);
|
||||
XAxiDmaCapture(xAxiDma0Get(),capture_length);
|
||||
n = capture_length*8;
|
||||
total_send = 0;
|
||||
/* handle request */
|
||||
while(n>0){
|
||||
if(n>1024)
|
||||
send_n = 1024;
|
||||
else
|
||||
send_n = n;
|
||||
n= n-send_n;
|
||||
memcpy(recv_buf,TX_BUFFER_BASE + total_send,send_n);
|
||||
total_send = total_send + send_n;
|
||||
if ((nwrote = write(sd, &recv_buf, send_n)) < 0) {
|
||||
xil_printf("%s: ERROR responding to client echo request. received = %d, written = %d\r\n",__FUNCTION__, n, nwrote);
|
||||
xil_printf("Closing socket %d\r\n", sd);
|
||||
break;
|
||||
}
|
||||
else{
|
||||
if(send_n!=nwrote){
|
||||
xil_printf("%d Bytes Send %d.\r\n", send_n,nwrote);
|
||||
}
|
||||
}
|
||||
}
|
||||
dbg_printf("Send %d bytes.\r\n",n);
|
||||
break;
|
||||
case CMD_DATA_CAPTURE1:
|
||||
read(sd, &recv_buf[5], 4);
|
||||
capture_length = *((u32 *) &recv_buf[5]);//num of sample
|
||||
dbg_printf("Rece cmd excute %d sample data capture.\r\n",capture_length);
|
||||
XAxiDmaCapture(xAxiDma1Get(),capture_length);
|
||||
n = capture_length*8;
|
||||
total_send = 0;
|
||||
/* handle request */
|
||||
while(n>0){
|
||||
if(n>1024)
|
||||
send_n = 1024;
|
||||
else
|
||||
send_n = n;
|
||||
n= n-send_n;
|
||||
|
||||
memcpy(recv_buf,TX_BUFFER_BASE + total_send,send_n);
|
||||
total_send = total_send + send_n;
|
||||
if ((nwrote = write(sd, &recv_buf, send_n)) < 0) {
|
||||
xil_printf("%s: ERROR responding to client echo request. received = %d, written = %d\r\n",__FUNCTION__, n, nwrote);
|
||||
xil_printf("Closing socket %d\r\n", sd);
|
||||
break;
|
||||
}
|
||||
else{
|
||||
if(send_n!=nwrote){
|
||||
xil_printf("%d Bytes Send %d.\r\n", send_n,nwrote);
|
||||
}
|
||||
}
|
||||
}
|
||||
dbg_printf("Send %d bytes.\r\n",n);
|
||||
break;
|
||||
case CMD_DATA_CAPTURE2:
|
||||
read(sd, &recv_buf[5], 4);
|
||||
capture_length = *((u32 *) &recv_buf[5]);//num of sample
|
||||
dbg_printf("Rece cmd excute %d sample data capture.\r\n",capture_length);
|
||||
XAxiDmaCapture(xAxiDma2Get(),capture_length);
|
||||
n = capture_length*8;
|
||||
total_send = 0;
|
||||
/* handle request */
|
||||
while(n>0){
|
||||
if(n>1024)
|
||||
send_n = 1024;
|
||||
else
|
||||
send_n = n;
|
||||
n= n-send_n;
|
||||
memcpy(recv_buf,TX_BUFFER_BASE + total_send,send_n);
|
||||
total_send = total_send + send_n;
|
||||
if ((nwrote = write(sd, &recv_buf, send_n)) < 0) {
|
||||
xil_printf("%s: ERROR responding to client echo request. received = %d, written = %d\r\n",__FUNCTION__, n, nwrote);
|
||||
xil_printf("Closing socket %d\r\n", sd);
|
||||
break;
|
||||
}
|
||||
else{
|
||||
if(send_n!=nwrote){
|
||||
xil_printf("%d Bytes Send %d.\r\n", send_n,nwrote);
|
||||
}
|
||||
}
|
||||
}
|
||||
dbg_printf("Send %d bytes.\r\n",n);
|
||||
break;
|
||||
case CMD_WAVE_DOWNLOAD:
|
||||
dbg_printf("Rece cmd excute wave download.\r\n");
|
||||
while(n<WAVE_LENGTH){
|
||||
dbg_printf("Rece data num in recv_buf is %d.\r\n",n);
|
||||
n =n + read(sd, &trans_buf[n], 512);//
|
||||
}
|
||||
dbg_printf("Rece data num in recv_buf is %d.\r\n",n);
|
||||
DownloadWave((u8 *)&trans_buf[0]);
|
||||
n=0;
|
||||
break;
|
||||
case CMD_PIN_SET:
|
||||
read(sd, &recv_buf[5], 2);
|
||||
pin = (u8) recv_buf[5];
|
||||
pin_value = (u8) recv_buf[6];
|
||||
dbg_printf("Rece cmd excute pin %d set %d.\r\n",pin,pin_value);
|
||||
GpioWritePin(pin,pin_value&0x01);
|
||||
break;
|
||||
|
||||
case CMD_hopping:
|
||||
read(sd, &recv_buf[5], 4);
|
||||
int hop_flag=recv_buf[5]&0x01;
|
||||
frqhop_flag(hop_flag);
|
||||
if(hop_flag==1){
|
||||
xil_printf("hopping freqence start.\r\n");
|
||||
}else{
|
||||
xil_printf("hopping freqence end.\r\n");
|
||||
}
|
||||
break;
|
||||
case CMD_qecbin:
|
||||
download_bin();
|
||||
break;
|
||||
case CMD_cx9261a_config:
|
||||
cx9261a_config();
|
||||
break;
|
||||
|
||||
case CMD_cx3e04_config:
|
||||
cx3e04_config();
|
||||
break;
|
||||
|
||||
case CMD_cx3e04_SPI_WRI:
|
||||
read(sd, &recv_buf[5], 3);
|
||||
dbg_printf("Rece cmd excute cx3e04_spi write.\r\n");
|
||||
dbg_printf("ADDR 0x%x DATA 0x%x.\r\n",recv_buf[5]*256+recv_buf[6]-32768,recv_buf[7]);
|
||||
int addr = recv_buf[5]*256+recv_buf[6];
|
||||
int value= recv_buf[7];
|
||||
cx3e04_write(addr,value);
|
||||
break;
|
||||
case CMD_cx3e04_SPI_READ:
|
||||
read(sd, &recv_buf[5], 2);
|
||||
dbg_printf("Rece cmd excute cx3e04_spi read.\r\n");
|
||||
dbg_printf("ADDR 0x%x.\r\n",recv_buf[5]*256+recv_buf[6]);
|
||||
addr = recv_buf[5]*256+recv_buf[6];
|
||||
n=1;
|
||||
recv_buf[0] = cx3e04_read(addr);
|
||||
break;
|
||||
default :
|
||||
xil_printf("cmd error 0x%x",recv_buf[4]);
|
||||
break;
|
||||
}
|
||||
|
||||
/*if(recv_buf[4] == 7){
|
||||
read(sd, &recv_buf[5], 4);
|
||||
capture_length = *((u32 *) &recv_buf[5]);//num of sample
|
||||
dbg_printf("Rece cmd excute %d sample data capture.\r\n",capture_length);
|
||||
XAxiDmaCapture2(capture_length);
|
||||
// memcpy(recv_buf,TX_BUFFER_BASE,capture_length*8);
|
||||
n = capture_length*8;
|
||||
total_send = 0;
|
||||
// handle request
|
||||
while(n>0){
|
||||
if(n>1024)
|
||||
send_n = 1024;
|
||||
else
|
||||
send_n = n;
|
||||
n= n-send_n;
|
||||
total_send = total_send + send_n;
|
||||
memcpy(recv_buf,TX_BUFFER_BASE + total_send,send_n);
|
||||
if ((nwrote = write(sd, &recv_buf, send_n)) < 0) {
|
||||
xil_printf("%s: ERROR responding to client echo request. received = %d, written = %d\r\n",
|
||||
__FUNCTION__, n, nwrote);
|
||||
xil_printf("Closing socket %d\r\n", sd);
|
||||
break;
|
||||
}
|
||||
else{
|
||||
if(send_n!=nwrote){
|
||||
xil_printf("%d Bytes Send %d.\r\n", send_n,nwrote);
|
||||
}
|
||||
}
|
||||
}
|
||||
dbg_printf("Send %d bytes.\r\n",n);
|
||||
}*/
|
||||
|
||||
}
|
||||
}
|
||||
/* handle request */
|
||||
if ((nwrote = write(sd, recv_buf, n)) < 0) {
|
||||
xil_printf("%s: ERROR responding to client echo request. received = %d, written = %d\r\n",
|
||||
__FUNCTION__, n, nwrote);
|
||||
xil_printf("Closing socket %d\r\n", sd);
|
||||
break;
|
||||
}
|
||||
else{
|
||||
if(n!=nwrote){
|
||||
xil_printf("%d Bytes Send %d.\r\n", n,nwrote);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* close connection */
|
||||
close(sd);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void echo_application_thread()
|
||||
{
|
||||
int sock, new_sd;
|
||||
int size;
|
||||
#if LWIP_IPV6==0
|
||||
struct sockaddr_in address, remote;
|
||||
|
||||
memset(&address, 0, sizeof(address));
|
||||
|
||||
if ((sock = lwip_socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||
return;
|
||||
|
||||
address.sin_family = AF_INET;
|
||||
address.sin_port = htons(echo_port);
|
||||
address.sin_addr.s_addr = INADDR_ANY;
|
||||
#else
|
||||
struct sockaddr_in6 address, remote;
|
||||
|
||||
memset(&address, 0, sizeof(address));
|
||||
|
||||
address.sin6_len = sizeof(address);
|
||||
address.sin6_family = AF_INET6;
|
||||
address.sin6_port = htons(echo_port);
|
||||
|
||||
memset(&(address.sin6_addr), 0, sizeof(address.sin6_addr));
|
||||
|
||||
if ((sock = lwip_socket(AF_INET6, SOCK_STREAM, 0)) < 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (lwip_bind(sock, (struct sockaddr *)&address, sizeof (address)) < 0)
|
||||
return;
|
||||
|
||||
lwip_listen(sock, 0);
|
||||
|
||||
size = sizeof(remote);
|
||||
|
||||
while (1) {
|
||||
if ((new_sd = lwip_accept(sock, (struct sockaddr *)&remote, (socklen_t *)&size)) > 0) {
|
||||
sys_thread_new("echos", process_echo_request,
|
||||
(void*)new_sd,
|
||||
THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
}
|
||||
}
|
||||
}
|
||||
+260
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* frqhop_config.c
|
||||
*
|
||||
* Created on: 2023年11月24日
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
#include "xilinx_io.h"
|
||||
#include "sleep.h"
|
||||
#include "time.h"
|
||||
#include "xtime_l.h"
|
||||
#include "math.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
void frqhop_config(int hop_flag){
|
||||
XTime tCur;
|
||||
XTime_GetTime(&tCur);
|
||||
srand(tCur);
|
||||
// double hop_freq = (rand()%(800-30))+30+(rand()%(101))/(double)100;//随机产生[30,800)double类型的数
|
||||
double hop_freq = 400.52;
|
||||
double hop_freq1 = 800.25;
|
||||
static int pll_index=1;
|
||||
static int unlock_pll1_cnt=0,unlock_pll2_cnt=0;
|
||||
if(hop_freq == hop_freq1){
|
||||
if(pll_index == 2){
|
||||
pll_index = 4;
|
||||
}
|
||||
else if(pll_index == 1){
|
||||
pll_index = 3;
|
||||
}
|
||||
}
|
||||
if(hop_flag == 1){
|
||||
if(pll_index == 1)
|
||||
{
|
||||
//切换至pll2来源
|
||||
trx_ch_pll_config(2);
|
||||
//配置pll1参数
|
||||
unlock_pll1_cnt=PLL_config(1,hop_freq)-1;
|
||||
pll_index = 2;
|
||||
}
|
||||
else if(pll_index == 2){
|
||||
//切换至pll1来源
|
||||
trx_ch_pll_config(1);
|
||||
//配置pll2参数
|
||||
unlock_pll2_cnt=PLL_config(2,hop_freq1)-1;
|
||||
pll_index = 1;
|
||||
}
|
||||
else if(pll_index == 3 )
|
||||
{
|
||||
//切换至pll2来源
|
||||
trx_ch_pll_config(2);
|
||||
pll_index = 2;
|
||||
}
|
||||
else if(pll_index == 4 ){
|
||||
//切换至pll1来源
|
||||
trx_ch_pll_config(1);
|
||||
pll_index = 1;
|
||||
}
|
||||
}
|
||||
hop_freq1 = hop_freq;
|
||||
if(unlock_pll2_cnt!=0 || unlock_pll1_cnt !=0){
|
||||
xil_printf("pll1 unlock num: %d; pll2 unlock num: %d;.\n", unlock_pll1_cnt, unlock_pll2_cnt);
|
||||
}
|
||||
}
|
||||
|
||||
u16 pll1_config_addr[] ={0x0620,0x061D,0x0B06,0x0B07,0x0B08,0x0B09,0x0B0A,0x061A,0x061B,0x061C,0x062A};
|
||||
u16 pll2_config_addr[] ={0x0642,0x063F,0x0B14,0x0B15,0x0B16,0x0B17,0x0B18,0x063C,0x063D,0x063E,0x064C};
|
||||
u16 pll3_config_addr[] ={0x0664,0x0661,0x0B22,0x0B23,0x0B24,0x0B25,0x0B26,0x065E,0x065F,0x0660,0x066E};
|
||||
u16 pll4_config_addr[] ={0x0686,0x0683,0x0B30,0x0B31,0x0B32,0x0B33,0x0B34,0x0680,0x0681,0x0682,0x0690};
|
||||
|
||||
int PLL_config(u8 pll_index,double pll_frq)
|
||||
{
|
||||
|
||||
int i = 0,afc_cnt=0;
|
||||
u16 pll_config_addr[11];
|
||||
u16 afc_addr,lock_addr;
|
||||
double ref=100;
|
||||
u8 pllreg_buf[11];
|
||||
u8 recv_buf[3];
|
||||
u8 rx_data,pll_div;
|
||||
u16 div_addr;
|
||||
|
||||
switch(pll_index){
|
||||
case 1:for (i = 0; i < 11; i++){pll_config_addr[i] = pll1_config_addr[i];} afc_addr=0x0617;lock_addr=0x0635;break;
|
||||
case 2:for (i = 0; i < 11; i++){pll_config_addr[i] = pll2_config_addr[i];} afc_addr=0x0639;lock_addr=0x0657;break;
|
||||
case 3:for (i = 0; i < 11; i++){pll_config_addr[i] = pll3_config_addr[i];} afc_addr=0x065B;lock_addr=0x0679;break;
|
||||
case 4:for (i = 0; i < 11; i++){pll_config_addr[i] = pll4_config_addr[i];} afc_addr=0x067D;lock_addr=0x069B;break;
|
||||
default :;
|
||||
}
|
||||
//caculate pll frequence word
|
||||
pll_frq_caculation_new(ref,pll_frq,(u8 *)&pllreg_buf);
|
||||
for (i = 0; i < 11; i++)
|
||||
{
|
||||
recv_buf[0] = (pll_config_addr[i]>>8 & 0xff)|0x80 ;
|
||||
recv_buf[1] = pll_config_addr[i] & 0xff;
|
||||
recv_buf[2] = pllreg_buf[i] & 0xff;
|
||||
SpiPs_write_read((u8 *)&recv_buf[0],&rx_data);
|
||||
}
|
||||
//afc pll
|
||||
pll_div = pllreg_buf[1];
|
||||
div_addr = pll_config_addr[1];
|
||||
recv_buf[0] = lock_addr>>8 & 0xff ;
|
||||
recv_buf[1] = lock_addr & 0xff;
|
||||
recv_buf[2] = 0x00;
|
||||
rx_data = 0;
|
||||
while(rx_data!=48){
|
||||
PLL_afc(afc_addr,div_addr,pll_div);
|
||||
SpiPs_write_read((u8 *)&recv_buf[0],&rx_data);
|
||||
afc_cnt++;
|
||||
}
|
||||
return afc_cnt;
|
||||
//xil_printf("afc lock count: %d.\r\n",afc_cnt);
|
||||
|
||||
}
|
||||
void trx_ch_pll_config(u8 pll_index)
|
||||
{
|
||||
u8 rx_data;
|
||||
u8 recv_buf[3]={0};
|
||||
u32 trx_ch_pll_data;
|
||||
|
||||
if(pll_index==1){
|
||||
trx_ch_pll_data = 0x00077DCF;
|
||||
}else if(pll_index==2){
|
||||
trx_ch_pll_data = 0x00077D0C;
|
||||
}
|
||||
|
||||
recv_buf[0] =(trx_ch_pll_data>>16 & 0xff)|0x80 ;
|
||||
recv_buf[1] = trx_ch_pll_data>>8 & 0xff;
|
||||
recv_buf[2] = trx_ch_pll_data & 0xff;
|
||||
SpiPs_write_read(recv_buf,&rx_data);
|
||||
}
|
||||
void PLL_afc(u16 afc_addr,u16 div_addr,u8 pll_div){
|
||||
|
||||
u8 recv_buf[3];
|
||||
u8 rx_data;
|
||||
if(pll_div>=48){
|
||||
recv_buf[0] = (div_addr>>8 & 0xff)|0x80 ;
|
||||
recv_buf[1] = div_addr & 0xff;
|
||||
recv_buf[2] = pll_div & 0x2f;
|
||||
SpiPs_write_read((u8 *)&recv_buf[0],&rx_data);
|
||||
}
|
||||
recv_buf[0] = (afc_addr>>8 & 0xff)|0x80 ;
|
||||
recv_buf[1] = afc_addr & 0xff;
|
||||
recv_buf[2] = 0x00;
|
||||
SpiPs_write_read((u8 *)&recv_buf[0],&rx_data);
|
||||
recv_buf[2] = 0x13;
|
||||
SpiPs_write_read((u8 *)&recv_buf[0],&rx_data);
|
||||
usleep(40);
|
||||
if(pll_div>=48){
|
||||
recv_buf[0] = (div_addr>>8 & 0xff)|0x80 ;
|
||||
recv_buf[1] = div_addr & 0xff;
|
||||
recv_buf[2] = pll_div & 0xff;
|
||||
SpiPs_write_read((u8 *)&recv_buf[0],&rx_data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int pll_frq_caculation_new(double ref,double pll_frq,u8 *reg_data){
|
||||
|
||||
u8 row,column;
|
||||
double vco = pll_frq;
|
||||
int div = 1;
|
||||
while(vco < 6701){
|
||||
vco = vco*2;
|
||||
div = div*2;
|
||||
}
|
||||
char coreTable[7][4][3] = {{{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}}};
|
||||
|
||||
if (ref >= 28 && ref < 40){
|
||||
row = 0;
|
||||
}else if (ref >= 40 && ref < 60){
|
||||
row = 1;
|
||||
}else if (ref >= 60 && ref < 90){
|
||||
row = 2;
|
||||
}else if (ref >= 90 && ref < 110){
|
||||
row = 3;
|
||||
}else if (ref >= 110 && ref < 140){
|
||||
row = 4;
|
||||
}else if (ref >= 140 && ref < 180){
|
||||
row = 5;
|
||||
}else if (ref >= 180 && ref <= 240){
|
||||
row = 6;
|
||||
}
|
||||
|
||||
if (vco < 8400){
|
||||
column = 0;
|
||||
}else if (vco >= 8400 && vco < 10150){
|
||||
column = 1;
|
||||
}else if (vco >= 10150 && vco < 12000){
|
||||
column = 2;
|
||||
}else if (vco >= 12000 ){
|
||||
column = 3;
|
||||
}
|
||||
|
||||
char cp = coreTable[row][column][0];
|
||||
char c1r3 = coreTable[row][column][1];
|
||||
char r1 = coreTable[row][column][2];
|
||||
|
||||
char dither,nHigh,nLow,fHigh,fMiddle,fLow,outputDiv,core = 0x81;
|
||||
if(vco > 10150){
|
||||
core = core + 0x10;
|
||||
}
|
||||
if (div == 2){
|
||||
outputDiv = 0+7;
|
||||
}else if (div == 4){
|
||||
outputDiv = 32+7;
|
||||
}else{
|
||||
outputDiv = 48 + divBin(div);
|
||||
}
|
||||
|
||||
double nf = (int64_t)(round(vco / ref * 1e9)) / 1.0e9;
|
||||
int n = nf;
|
||||
double f = nf - n;
|
||||
if(f > 1e-10){
|
||||
dither = 11;
|
||||
}else{
|
||||
dither = 0;
|
||||
}
|
||||
if(n >= 256){
|
||||
nHigh = 1;
|
||||
}else{
|
||||
nHigh = 0;
|
||||
}
|
||||
nLow = n & 0xff;
|
||||
int f1 = f * pow(2,24);
|
||||
fHigh = f1>>16 & 0xff;
|
||||
fMiddle = f1>>8 & 0xff;
|
||||
fLow = f1 & 0xff;
|
||||
reg_data[0]=core;
|
||||
reg_data[1]=outputDiv;
|
||||
reg_data[2]=nHigh;
|
||||
reg_data[3]=nLow;
|
||||
reg_data[4]=fHigh;
|
||||
reg_data[5]=fMiddle;
|
||||
reg_data[6]=fLow;
|
||||
reg_data[7]=cp;
|
||||
reg_data[8]=c1r3;
|
||||
reg_data[9]=r1;
|
||||
reg_data[10]=dither;
|
||||
return 0;
|
||||
}
|
||||
char divBin(u16 div){
|
||||
|
||||
switch(div){
|
||||
case 8:return 7;break;
|
||||
case 16:return 6;break;
|
||||
case 32:return 5;break;
|
||||
case 64:return 4;break;
|
||||
case 128:return 3;break;
|
||||
case 256:return 2;break;
|
||||
default :return 2;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (C) 2016 - 2018 Xilinx, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "xparameters.h"
|
||||
#if defined (__arm__) || defined(__aarch64__)
|
||||
#include "xil_printf.h"
|
||||
#endif
|
||||
|
||||
#ifdef XPS_BOARD_ZCU102
|
||||
#ifdef XPAR_XIICPS_0_DEVICE_ID
|
||||
#include "xiicps.h"
|
||||
|
||||
#define BUF_LEN 10U
|
||||
|
||||
#define IOEXPANDER1_ADDR 0x20U
|
||||
|
||||
#define IIC_SCLK_RATE_IOEXP 400000
|
||||
|
||||
#define CMD_CFG_0_REG 0x06U
|
||||
#define CMD_OUTPUT_0_REG 0x02U
|
||||
#define DATA_OUTPUT 0x0U
|
||||
|
||||
#define DATA_COMMON_CFG 0xE0U
|
||||
#define DATA_GT_0000_CFG 0x00U
|
||||
|
||||
XIicPs I2c0InstancePtr;
|
||||
|
||||
int IicPhyReset(void)
|
||||
{
|
||||
|
||||
u8 WriteBuffer[BUF_LEN] = {0};
|
||||
XIicPs_Config *I2c0CfgPtr;
|
||||
int Status = XST_SUCCESS;
|
||||
|
||||
/* Initialize the IIC0 driver so that it is ready to use */
|
||||
I2c0CfgPtr = XIicPs_LookupConfig(XPAR_XIICPS_0_DEVICE_ID);
|
||||
if (I2c0CfgPtr == NULL) {
|
||||
Status = XST_FAILURE;
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = XIicPs_CfgInitialize(&I2c0InstancePtr, I2c0CfgPtr,
|
||||
I2c0CfgPtr->BaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
Status = XST_FAILURE;
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set the IIC serial clock rate */
|
||||
XIicPs_SetSClk(&I2c0InstancePtr, IIC_SCLK_RATE_IOEXP);
|
||||
|
||||
/* Configure I/O pins as Output */
|
||||
WriteBuffer[0] = CMD_CFG_0_REG;
|
||||
WriteBuffer[1] = DATA_OUTPUT;
|
||||
Status = XIicPs_MasterSendPolled(&I2c0InstancePtr,
|
||||
WriteBuffer, 2, IOEXPANDER1_ADDR);
|
||||
if (Status != XST_SUCCESS) {
|
||||
Status = XST_FAILURE;
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Wait until bus is idle to start another transfer */
|
||||
while (XIicPs_BusIsBusy(&I2c0InstancePtr));
|
||||
|
||||
/*
|
||||
* Deasserting I2C_MUX_RESETB
|
||||
* And GEM3 Resetb
|
||||
* Selecting lanes based on configuration
|
||||
*/
|
||||
WriteBuffer[0] = CMD_OUTPUT_0_REG;
|
||||
/* gt0000 or no GT configuration */
|
||||
WriteBuffer[1] = DATA_COMMON_CFG | DATA_GT_0000_CFG;
|
||||
|
||||
/* Send the Data */
|
||||
Status = XIicPs_MasterSendPolled(&I2c0InstancePtr,
|
||||
WriteBuffer, 2, IOEXPANDER1_ADDR);
|
||||
if (Status != XST_SUCCESS) {
|
||||
Status = XST_FAILURE;
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Wait until bus is idle */
|
||||
while (XIicPs_BusIsBusy(&I2c0InstancePtr));
|
||||
|
||||
xil_printf("IIC PHY reset on ZCU102 successful \n\r");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,291 @@
|
||||
/*******************************************************************/
|
||||
/* */
|
||||
/* This file is automatically generated by linker script generator.*/
|
||||
/* */
|
||||
/* Version: 2018.3 */
|
||||
/* */
|
||||
/* Copyright (c) 2010-2016 Xilinx, Inc. All rights reserved. */
|
||||
/* */
|
||||
/* Description : Cortex-A9 Linker Script */
|
||||
/* */
|
||||
/*******************************************************************/
|
||||
|
||||
_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x400;
|
||||
_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x400;
|
||||
|
||||
_ABORT_STACK_SIZE = DEFINED(_ABORT_STACK_SIZE) ? _ABORT_STACK_SIZE : 1024;
|
||||
_SUPERVISOR_STACK_SIZE = DEFINED(_SUPERVISOR_STACK_SIZE) ? _SUPERVISOR_STACK_SIZE : 2048;
|
||||
_IRQ_STACK_SIZE = DEFINED(_IRQ_STACK_SIZE) ? _IRQ_STACK_SIZE : 1024;
|
||||
_FIQ_STACK_SIZE = DEFINED(_FIQ_STACK_SIZE) ? _FIQ_STACK_SIZE : 1024;
|
||||
_UNDEF_STACK_SIZE = DEFINED(_UNDEF_STACK_SIZE) ? _UNDEF_STACK_SIZE : 1024;
|
||||
|
||||
/* Define Memories in the system */
|
||||
|
||||
MEMORY
|
||||
{
|
||||
axi_bram_ctrl_0_Mem0 : ORIGIN = 0x42000000, LENGTH = 0x8000
|
||||
axi_bram_ctrl_1_Mem0 : ORIGIN = 0x43000000, LENGTH = 0x8000
|
||||
mig_7series_0_memaddr : ORIGIN = 0x80000000, LENGTH = 0x40000000
|
||||
ps7_ddr_0 : ORIGIN = 0x100000, LENGTH = 0x3FF00000
|
||||
ps7_qspi_linear_0 : ORIGIN = 0xFC000000, LENGTH = 0x2000000
|
||||
ps7_ram_0 : ORIGIN = 0x0, LENGTH = 0x30000
|
||||
ps7_ram_1 : ORIGIN = 0xFFFF0000, LENGTH = 0xFE00
|
||||
}
|
||||
|
||||
/* Specify the default entry point to the program */
|
||||
|
||||
ENTRY(_vector_table)
|
||||
|
||||
/* Define the sections, and where they are mapped in memory */
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : {
|
||||
KEEP (*(.vectors))
|
||||
*(.boot)
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
*(.plt)
|
||||
*(.gnu_warning)
|
||||
*(.gcc_execpt_table)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.vfp11_veneer)
|
||||
*(.ARM.extab)
|
||||
*(.gnu.linkonce.armextab.*)
|
||||
} > ps7_ddr_0
|
||||
|
||||
.init : {
|
||||
KEEP (*(.init))
|
||||
} > ps7_ddr_0
|
||||
|
||||
.fini : {
|
||||
KEEP (*(.fini))
|
||||
} > ps7_ddr_0
|
||||
|
||||
.rodata : {
|
||||
__rodata_start = .;
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
__rodata_end = .;
|
||||
} > ps7_ddr_0
|
||||
|
||||
.rodata1 : {
|
||||
__rodata1_start = .;
|
||||
*(.rodata1)
|
||||
*(.rodata1.*)
|
||||
__rodata1_end = .;
|
||||
} > ps7_ddr_0
|
||||
|
||||
.sdata2 : {
|
||||
__sdata2_start = .;
|
||||
*(.sdata2)
|
||||
*(.sdata2.*)
|
||||
*(.gnu.linkonce.s2.*)
|
||||
__sdata2_end = .;
|
||||
} > ps7_ddr_0
|
||||
|
||||
.sbss2 : {
|
||||
__sbss2_start = .;
|
||||
*(.sbss2)
|
||||
*(.sbss2.*)
|
||||
*(.gnu.linkonce.sb2.*)
|
||||
__sbss2_end = .;
|
||||
} > ps7_ddr_0
|
||||
|
||||
.data : {
|
||||
__data_start = .;
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
*(.jcr)
|
||||
*(.got)
|
||||
*(.got.plt)
|
||||
__data_end = .;
|
||||
} > ps7_ddr_0
|
||||
|
||||
.data1 : {
|
||||
__data1_start = .;
|
||||
*(.data1)
|
||||
*(.data1.*)
|
||||
__data1_end = .;
|
||||
} > ps7_ddr_0
|
||||
|
||||
.got : {
|
||||
*(.got)
|
||||
} > ps7_ddr_0
|
||||
|
||||
.ctors : {
|
||||
__CTOR_LIST__ = .;
|
||||
___CTORS_LIST___ = .;
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
__CTOR_END__ = .;
|
||||
___CTORS_END___ = .;
|
||||
} > ps7_ddr_0
|
||||
|
||||
.dtors : {
|
||||
__DTOR_LIST__ = .;
|
||||
___DTORS_LIST___ = .;
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
__DTOR_END__ = .;
|
||||
___DTORS_END___ = .;
|
||||
} > ps7_ddr_0
|
||||
|
||||
.fixup : {
|
||||
__fixup_start = .;
|
||||
*(.fixup)
|
||||
__fixup_end = .;
|
||||
} > ps7_ddr_0
|
||||
|
||||
.eh_frame : {
|
||||
*(.eh_frame)
|
||||
} > ps7_ddr_0
|
||||
|
||||
.eh_framehdr : {
|
||||
__eh_framehdr_start = .;
|
||||
*(.eh_framehdr)
|
||||
__eh_framehdr_end = .;
|
||||
} > ps7_ddr_0
|
||||
|
||||
.gcc_except_table : {
|
||||
*(.gcc_except_table)
|
||||
} > ps7_ddr_0
|
||||
|
||||
.mmu_tbl (ALIGN(16384)) : {
|
||||
__mmu_tbl_start = .;
|
||||
*(.mmu_tbl)
|
||||
__mmu_tbl_end = .;
|
||||
} > ps7_ddr_0
|
||||
|
||||
.ARM.exidx : {
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx*)
|
||||
*(.gnu.linkonce.armexidix.*.*)
|
||||
__exidx_end = .;
|
||||
} > ps7_ddr_0
|
||||
|
||||
.preinit_array : {
|
||||
__preinit_array_start = .;
|
||||
KEEP (*(SORT(.preinit_array.*)))
|
||||
KEEP (*(.preinit_array))
|
||||
__preinit_array_end = .;
|
||||
} > ps7_ddr_0
|
||||
|
||||
.init_array : {
|
||||
__init_array_start = .;
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
__init_array_end = .;
|
||||
} > ps7_ddr_0
|
||||
|
||||
.fini_array : {
|
||||
__fini_array_start = .;
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
KEEP (*(.fini_array))
|
||||
__fini_array_end = .;
|
||||
} > ps7_ddr_0
|
||||
|
||||
.ARM.attributes : {
|
||||
__ARM.attributes_start = .;
|
||||
*(.ARM.attributes)
|
||||
__ARM.attributes_end = .;
|
||||
} > ps7_ddr_0
|
||||
|
||||
.sdata : {
|
||||
__sdata_start = .;
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
__sdata_end = .;
|
||||
} > ps7_ddr_0
|
||||
|
||||
.sbss (NOLOAD) : {
|
||||
__sbss_start = .;
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
*(.gnu.linkonce.sb.*)
|
||||
__sbss_end = .;
|
||||
} > ps7_ddr_0
|
||||
|
||||
.tdata : {
|
||||
__tdata_start = .;
|
||||
*(.tdata)
|
||||
*(.tdata.*)
|
||||
*(.gnu.linkonce.td.*)
|
||||
__tdata_end = .;
|
||||
} > ps7_ddr_0
|
||||
|
||||
.tbss : {
|
||||
__tbss_start = .;
|
||||
*(.tbss)
|
||||
*(.tbss.*)
|
||||
*(.gnu.linkonce.tb.*)
|
||||
__tbss_end = .;
|
||||
} > ps7_ddr_0
|
||||
|
||||
.bss (NOLOAD) : {
|
||||
__bss_start = .;
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
__bss_end = .;
|
||||
} > ps7_ddr_0
|
||||
|
||||
_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 );
|
||||
|
||||
_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 );
|
||||
|
||||
/* Generate Stack and Heap definitions */
|
||||
|
||||
.heap (NOLOAD) : {
|
||||
. = ALIGN(16);
|
||||
_heap = .;
|
||||
HeapBase = .;
|
||||
_heap_start = .;
|
||||
. += _HEAP_SIZE;
|
||||
_heap_end = .;
|
||||
HeapLimit = .;
|
||||
} > ps7_ddr_0
|
||||
|
||||
.stack (NOLOAD) : {
|
||||
. = ALIGN(16);
|
||||
_stack_end = .;
|
||||
. += _STACK_SIZE;
|
||||
. = ALIGN(16);
|
||||
_stack = .;
|
||||
__stack = _stack;
|
||||
. = ALIGN(16);
|
||||
_irq_stack_end = .;
|
||||
. += _IRQ_STACK_SIZE;
|
||||
. = ALIGN(16);
|
||||
__irq_stack = .;
|
||||
_supervisor_stack_end = .;
|
||||
. += _SUPERVISOR_STACK_SIZE;
|
||||
. = ALIGN(16);
|
||||
__supervisor_stack = .;
|
||||
_abort_stack_end = .;
|
||||
. += _ABORT_STACK_SIZE;
|
||||
. = ALIGN(16);
|
||||
__abort_stack = .;
|
||||
_fiq_stack_end = .;
|
||||
. += _FIQ_STACK_SIZE;
|
||||
. = ALIGN(16);
|
||||
__fiq_stack = .;
|
||||
_undef_stack_end = .;
|
||||
. += _UNDEF_STACK_SIZE;
|
||||
. = ALIGN(16);
|
||||
__undef_stack = .;
|
||||
} > ps7_ddr_0
|
||||
|
||||
_end = .;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
* Copyright (C) 2016 - 2018 Xilinx, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "xparameters.h"
|
||||
#include "netif/xadapter.h"
|
||||
#include "platform_config.h"
|
||||
#include "xil_printf.h"
|
||||
#include "xilinx_io.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "queue.h"
|
||||
#include "semphr.h"
|
||||
#include "math.h"
|
||||
|
||||
#if LWIP_IPV6==1
|
||||
#include "lwip/ip.h"
|
||||
#else
|
||||
#if LWIP_DHCP==1
|
||||
#include "lwip/dhcp.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef XPS_BOARD_ZCU102
|
||||
#ifdef XPAR_XIICPS_0_DEVICE_ID
|
||||
int IicPhyReset(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int main_thread();
|
||||
void print_echo_app_header();
|
||||
void echo_application_thread(void *);
|
||||
|
||||
void lwip_init();
|
||||
|
||||
#if LWIP_IPV6==0
|
||||
#if LWIP_DHCP==1
|
||||
extern volatile int dhcp_timoutcntr;
|
||||
err_t dhcp_start(struct netif *netif);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define THREAD_STACKSIZE 1024
|
||||
|
||||
static struct netif server_netif;
|
||||
struct netif *echo_netif;
|
||||
|
||||
#if LWIP_IPV6==1
|
||||
void print_ip6(char *msg, ip_addr_t *ip)
|
||||
{
|
||||
print(msg);
|
||||
xil_printf(" %x:%x:%x:%x:%x:%x:%x:%x\n\r",
|
||||
IP6_ADDR_BLOCK1(&ip->u_addr.ip6),
|
||||
IP6_ADDR_BLOCK2(&ip->u_addr.ip6),
|
||||
IP6_ADDR_BLOCK3(&ip->u_addr.ip6),
|
||||
IP6_ADDR_BLOCK4(&ip->u_addr.ip6),
|
||||
IP6_ADDR_BLOCK5(&ip->u_addr.ip6),
|
||||
IP6_ADDR_BLOCK6(&ip->u_addr.ip6),
|
||||
IP6_ADDR_BLOCK7(&ip->u_addr.ip6),
|
||||
IP6_ADDR_BLOCK8(&ip->u_addr.ip6));
|
||||
}
|
||||
|
||||
#else
|
||||
void
|
||||
print_ip(char *msg, ip_addr_t *ip)
|
||||
{
|
||||
xil_printf(msg);
|
||||
xil_printf("%d.%d.%d.%d\n\r", ip4_addr1(ip), ip4_addr2(ip),
|
||||
ip4_addr3(ip), ip4_addr4(ip));
|
||||
}
|
||||
|
||||
void
|
||||
print_ip_settings(ip_addr_t *ip, ip_addr_t *mask, ip_addr_t *gw)
|
||||
{
|
||||
|
||||
print_ip("Board IP: ", ip);
|
||||
print_ip("Netmask : ", mask);
|
||||
print_ip("Gateway : ", gw);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
xil_printf("start \r\n");
|
||||
|
||||
sys_thread_new("main_thrd", (void(*)(void*))main_thread, 0,
|
||||
THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
vTaskStartScheduler();
|
||||
|
||||
while(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void network_thread(void *p)
|
||||
{
|
||||
struct netif *netif;
|
||||
/* the mac address of the board. this should be unique per board */
|
||||
unsigned char mac_ethernet_address[] = { 0x00, 0x0a, 0x35, 0x00, 0x01, 0x02 };
|
||||
#if LWIP_IPV6==0
|
||||
ip_addr_t ipaddr, netmask, gw;
|
||||
#if LWIP_DHCP==1
|
||||
int mscnt = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
netif = &server_netif;
|
||||
|
||||
xil_printf("\r\n\r\n");
|
||||
xil_printf("-----lwIP Socket Mode CX9261 TEST server Application Version 2022.05.31------\r\n");
|
||||
|
||||
#if LWIP_IPV6==0
|
||||
#if LWIP_DHCP==0
|
||||
/* initliaze IP addresses to be used */
|
||||
IP4_ADDR(&ipaddr, 192, 168, 1, 99);
|
||||
IP4_ADDR(&netmask, 255, 255, 255, 0);
|
||||
IP4_ADDR(&gw, 192, 168, 1, 1);
|
||||
#endif
|
||||
|
||||
/* print out IP settings of the board */
|
||||
|
||||
#if LWIP_DHCP==0
|
||||
print_ip_settings(&ipaddr, &netmask, &gw);
|
||||
/* print all application headers */
|
||||
#endif
|
||||
|
||||
#if LWIP_DHCP==1
|
||||
ipaddr.addr = 0;
|
||||
gw.addr = 0;
|
||||
netmask.addr = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LWIP_IPV6==0
|
||||
/* Add network interface to the netif_list, and set it as default */
|
||||
if (!xemac_add(netif, &ipaddr, &netmask, &gw, mac_ethernet_address, PLATFORM_EMAC_BASEADDR)) {
|
||||
xil_printf("Error adding N/W interface\r\n");
|
||||
return;
|
||||
}
|
||||
#else
|
||||
/* Add network interface to the netif_list, and set it as default */
|
||||
if (!xemac_add(netif, NULL, NULL, NULL, mac_ethernet_address, PLATFORM_EMAC_BASEADDR)) {
|
||||
xil_printf("Error adding N/W interface\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
netif->ip6_autoconfig_enabled = 1;
|
||||
|
||||
netif_create_ip6_linklocal_address(netif, 1);
|
||||
netif_ip6_addr_set_state(netif, 0, IP6_ADDR_VALID);
|
||||
|
||||
print_ip6("\n\rBoard IPv6 address ", &netif->ip6_addr[0].u_addr.ip6);
|
||||
#endif
|
||||
|
||||
netif_set_default(netif);
|
||||
|
||||
/* specify that the network if is up */
|
||||
netif_set_up(netif);
|
||||
|
||||
/* start packet receive thread - required for lwIP operation */
|
||||
sys_thread_new("xemacif_input_thread", (void(*)(void*))xemacif_input_thread, netif,
|
||||
THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
|
||||
#if LWIP_IPV6==0
|
||||
#if LWIP_DHCP==1
|
||||
dhcp_start(netif);
|
||||
while (1) {
|
||||
vTaskDelay(DHCP_FINE_TIMER_MSECS / portTICK_RATE_MS);
|
||||
dhcp_fine_tmr();
|
||||
mscnt += DHCP_FINE_TIMER_MSECS;
|
||||
if (mscnt >= DHCP_COARSE_TIMER_SECS*1000) {
|
||||
dhcp_coarse_tmr();
|
||||
mscnt = 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
xil_printf("\r\n");
|
||||
xil_printf("%20s %6s %s\r\n", "Server", "Port", "Connect With..");
|
||||
xil_printf("%20s %6s %s\r\n", "--------------------", "------", "--------------------");
|
||||
|
||||
print_echo_app_header();
|
||||
xil_printf("\r\n");
|
||||
sys_thread_new("echod", echo_application_thread, 0,
|
||||
THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
vTaskDelete(NULL);
|
||||
#endif
|
||||
#else
|
||||
print_echo_app_header();
|
||||
xil_printf("\r\n");
|
||||
sys_thread_new("echod",echo_application_thread, 0,
|
||||
THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
vTaskDelete(NULL);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
int main_thread()
|
||||
{
|
||||
#if LWIP_DHCP==1
|
||||
int mscnt = 0;
|
||||
#endif
|
||||
|
||||
#ifdef XPS_BOARD_ZCU102
|
||||
IicPhyReset();
|
||||
#endif
|
||||
|
||||
/* initialize lwIP before calling sys_thread_new */
|
||||
lwip_init();
|
||||
SpiPsInit(SPI_DEVICE_ID);
|
||||
GpioInit(GPIO_DEVICE_ID);
|
||||
AXIGpioInit();
|
||||
XScuGicInit();
|
||||
ConfigAXIGPIOIntr();
|
||||
ExceptionInit();
|
||||
|
||||
XAxiDma_Init(xAxiDma0Get(),AXI_DMA_DEVCIE_ID0);
|
||||
XAxiDma_Init(xAxiDma1Get(),AXI_DMA_DEVCIE_ID1);
|
||||
XAxiDma_Init(xAxiDma2Get(),AXI_DMA_DEVCIE_ID2);
|
||||
PackerRst();
|
||||
|
||||
/* cx9261a configuration */
|
||||
peripheral_test();
|
||||
download_bin();
|
||||
// frqhop_config(1);
|
||||
/* any thread using lwIP should be created using sys_thread_new */
|
||||
sys_thread_new("NW_THRD", network_thread, NULL,
|
||||
THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
|
||||
#if LWIP_IPV6==0
|
||||
#if LWIP_DHCP==1
|
||||
while (1) {
|
||||
vTaskDelay(DHCP_FINE_TIMER_MSECS / portTICK_RATE_MS);
|
||||
if (server_netif.ip_addr.addr) {
|
||||
xil_printf("DHCP request success\r\n");
|
||||
print_ip_settings(&(server_netif.ip_addr), &(server_netif.netmask), &(server_netif.gw));
|
||||
print_echo_app_header();
|
||||
xil_printf("\r\n");
|
||||
sys_thread_new("echod", echo_application_thread, 0,
|
||||
THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
break;
|
||||
}
|
||||
mscnt += DHCP_FINE_TIMER_MSECS;
|
||||
if (mscnt >= 10000) {
|
||||
xil_printf("ERROR: DHCP request timed out\r\n");
|
||||
xil_printf("Configuring default IP of 192.168.1.100\r\n");
|
||||
IP4_ADDR(&(server_netif.ip_addr), 192, 168, 1, 100);
|
||||
IP4_ADDR(&(server_netif.netmask), 255, 255, 255, 0);
|
||||
IP4_ADDR(&(server_netif.gw), 192, 168, 1, 1);
|
||||
print_ip_settings(&(server_netif.ip_addr), &(server_netif.netmask), &(server_netif.gw));
|
||||
/* print all application headers */
|
||||
xil_printf("\r\n");
|
||||
xil_printf("%20s %6s %s\r\n", "Server", "Port", "Connect With..");
|
||||
xil_printf("%20s %6s %s\r\n", "--------------------", "------", "--------------------");
|
||||
|
||||
print_echo_app_header();
|
||||
xil_printf("\r\n");
|
||||
sys_thread_new("echod", echo_application_thread, 0,
|
||||
THREAD_STACKSIZE,
|
||||
DEFAULT_THREAD_PRIO);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
vTaskDelete(NULL);
|
||||
return 0;
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
#ifndef __PLATFORM_CONFIG_H_
|
||||
#define __PLATFORM_CONFIG_H_
|
||||
|
||||
|
||||
#define PLATFORM_EMAC_BASEADDR XPAR_XEMACPS_0_BASEADDR
|
||||
|
||||
#define PLATFORM_ZYNQ
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,178 @@
|
||||
#include "sd.h"
|
||||
/************************** Variable Definitions *****************************/
|
||||
static FIL fil; /* File object */
|
||||
static FATFS fatfs;
|
||||
/*
|
||||
* To test logical drive 0, FileName should be "0:/<File name>" or
|
||||
* "<file_name>". For logical drive 1, FileName should be "1:/<file_name>"
|
||||
*/
|
||||
static char FileName[32] = "BOOT.bin";
|
||||
static char *SD_File;
|
||||
|
||||
|
||||
//#define BUFF_SIZE sizeof(image_data)
|
||||
#define BUFF_SIZE 0x2000000
|
||||
#ifdef __ICCARM__
|
||||
#pragma data_alignment = 32
|
||||
u8 DestinationAddress[10*1024];
|
||||
#pragma data_alignment = 32
|
||||
u8 SourceAddress[10*1024];
|
||||
#else
|
||||
//u8 DestinationAddress[10*1024] __attribute__ ((aligned(32)));
|
||||
//u8 SourceAddress[10*1024] __attribute__ ((aligned(32)));
|
||||
|
||||
u8 DestinationAddress[BUFF_SIZE] __attribute__ ((aligned(32)));
|
||||
u8 SourceAddress[BUFF_SIZE] __attribute__ ((aligned(32)));
|
||||
#endif
|
||||
|
||||
#define TEST 7
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* File system example using SD driver to write to and read from an SD card
|
||||
* in polled mode. This example creates a new file on an
|
||||
* SD card (which is previously formatted with FATFS), write data to the file
|
||||
* and reads the same data back to verify.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
******************************************************************************/
|
||||
int FfsSdWrite(u8*image_data, u32 FileSize)
|
||||
{
|
||||
int error_flag = 0;
|
||||
FRESULT Res;
|
||||
UINT NumBytesRead;
|
||||
UINT NumBytesWritten;
|
||||
u32 BuffCnt;
|
||||
BYTE work[FF_MAX_SS];
|
||||
// u32 FileSize = (8*1024);
|
||||
// u32 FileSize = sizeof(image_data);
|
||||
/*
|
||||
* To test logical drive 0, Path should be "0:/"
|
||||
* For logical drive 1, Path should be "1:/"
|
||||
*/
|
||||
TCHAR *Path = "0:/";
|
||||
u8 checksum = 0;
|
||||
|
||||
for(BuffCnt = 0; BuffCnt < FileSize; BuffCnt++){
|
||||
// SourceAddress[BuffCnt] = TEST + BuffCnt;
|
||||
SourceAddress[BuffCnt] = image_data[BuffCnt];
|
||||
checksum = checksum + image_data[BuffCnt];
|
||||
}
|
||||
xil_printf("checksum is 0x%x.",checksum);
|
||||
|
||||
|
||||
/*
|
||||
* Register volume work area, initialize device
|
||||
*/
|
||||
Res = f_mount(&fatfs, Path, 0);
|
||||
|
||||
if (Res != FR_OK) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Path - Path to logical driver, 0 - FDISK format.
|
||||
* 0 - Cluster size is automatically determined based on Vol size.
|
||||
*/
|
||||
Res = f_mkfs(Path, FM_FAT32, 0, work, sizeof work);
|
||||
if (Res != FR_OK) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open file with required permissions.
|
||||
* Here - Creating new file with read/write permissions. .
|
||||
* To open file with write permissions, file system should not
|
||||
* be in Read Only mode.
|
||||
*/
|
||||
SD_File = (char *)FileName;
|
||||
|
||||
Res = f_open(&fil, SD_File, FA_CREATE_ALWAYS | FA_WRITE | FA_READ);
|
||||
if (Res) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pointer to beginning of file .
|
||||
*/
|
||||
Res = f_lseek(&fil, 0);
|
||||
if (Res) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write data to file.
|
||||
*/
|
||||
Res = f_write(&fil, (const void*)SourceAddress, FileSize,
|
||||
&NumBytesWritten);
|
||||
if (Res) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
/*
|
||||
* Close file.
|
||||
*/
|
||||
Res = f_close(&fil);
|
||||
if (Res) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
Res = f_open(&fil, SD_File, FA_READ);
|
||||
if (Res) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
/*
|
||||
* Pointer to beginning of file .
|
||||
*/
|
||||
Res = f_lseek(&fil, 0);
|
||||
if (Res) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read data from file.
|
||||
*/
|
||||
Res = f_read(&fil, (void*)DestinationAddress, FileSize,
|
||||
&NumBytesRead);
|
||||
if (Res) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Data verification
|
||||
*/
|
||||
for(BuffCnt = 0; BuffCnt < FileSize; BuffCnt++){
|
||||
if(SourceAddress[BuffCnt] != DestinationAddress[BuffCnt]){
|
||||
// return XST_FAILURE;
|
||||
error_flag = 1;
|
||||
xil_printf('Data check error.');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Close file.
|
||||
*/
|
||||
Res = f_close(&fil);
|
||||
if (Res) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
if(error_flag){
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
// Res = f_unmount(Path);
|
||||
// if (Res) {
|
||||
// return XST_FAILURE;
|
||||
// }
|
||||
//
|
||||
// sleep(5);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
/***************************** Include Files *********************************/
|
||||
#include "xparameters.h" /* SDK generated parameters */
|
||||
#include "xsdps.h" /* SD device driver */
|
||||
#include "xil_printf.h"
|
||||
#include "ff.h"
|
||||
#include "xil_cache.h"
|
||||
#include "xplatform_info.h"
|
||||
/************************** Function Prototypes ******************************/
|
||||
int FfsSdWrite(u8*image_data, u32 FileSize);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* xilinx_io.h
|
||||
*
|
||||
* Created on: 2021年9月6日
|
||||
* Author: cxlab
|
||||
*/
|
||||
|
||||
#ifndef SRC_XILINX_IO_H_
|
||||
#define SRC_XILINX_IO_H_
|
||||
|
||||
|
||||
|
||||
#endif /* SRC_XILINX_IO_H_ */
|
||||
#include "xspips.h" /* SPI device driver */
|
||||
#include "xgpiops.h"
|
||||
#include "xgpio.h"
|
||||
#include "xaxidma.h"
|
||||
#include "xparameters.h"
|
||||
#include "xscugic.h"
|
||||
#include "xil_exception.h"
|
||||
|
||||
//#define DBGLOG
|
||||
#define MAX_DATA 100
|
||||
#define SPI_WRITE 0x80
|
||||
#define SPI_READ 0x00
|
||||
#define GPIO_DIR_INPUT 0x00
|
||||
#define GPIO_DIR_OUTPUT 0x01
|
||||
#define GPIO_EMIO_OFFSET 54
|
||||
|
||||
#define TX_EN 0x08
|
||||
#define RX_EN 0x07
|
||||
#define GPIO_1 0x06
|
||||
#define GPIO_0 0x05
|
||||
|
||||
#define NRST 0
|
||||
#define ENABLE_TRX1 1
|
||||
#define ENABLE_TRX2 2
|
||||
#define ENABLE_TRX3 3
|
||||
#define TXNRX_TRX1 4
|
||||
#define TXNRX_TRX2 5
|
||||
#define TXNRX_RX3 6
|
||||
|
||||
#define aresetn_0 33
|
||||
#define rst 34
|
||||
#define tr_sel 35
|
||||
#define tdd_fdd_sel 36
|
||||
#define r1t1_r2t2_sel 37
|
||||
#define sp_dp_sel 38
|
||||
#define aresetn_1 39
|
||||
#define aresetn_2 40
|
||||
#define hop 41
|
||||
#define cx3e04_rstn 42
|
||||
#define spi_select 46
|
||||
#define debug_mode 63
|
||||
|
||||
|
||||
#define SPI_DEVICE_ID XPAR_XSPIPS_0_DEVICE_ID
|
||||
#define GPIO_DEVICE_ID XPAR_PS7_GPIO_0_DEVICE_ID
|
||||
|
||||
#define AXI_DMA_DEVCIE_ID0 XPAR_AXI_DMA_0_DEVICE_ID
|
||||
#define AXI_DMA_DEVCIE_ID1 XPAR_AXI_DMA_1_DEVICE_ID
|
||||
#define AXI_DMA_DEVCIE_ID2 XPAR_AXI_DMA_2_DEVICE_ID
|
||||
|
||||
#define BROM_BASEADDR XPAR_M08_AXI_0_BASEADDR
|
||||
|
||||
#define AXI4_LITE0_SPI_BASEADDR XPAR_AXI4_LITE_SPI_0_BASEADDR
|
||||
#define AXI4_LITE1_SPI_BASEADDR XPAR_AXI4_LITE_SPI_1_BASEADDR
|
||||
#define BRAM_BASEADDR XPAR_AXI_BRAM_CTRL_0_S_AXI_BASEADDR
|
||||
#define BRAM_BASEADDR_1 XPAR_AXI_BRAM_CTRL_1_S_AXI_BASEADDR
|
||||
#define PACKER_BASEADDR0 XPAR_AXIS_ADC_DATA_PACKER_0_S00_AXI_BASEADDR
|
||||
#define PACKER_BASEADDR1 XPAR_AXIS_ADC_DATA_PACKER_1_S00_AXI_BASEADDR
|
||||
#define PACKER_BASEADDR2 XPAR_AXIS_ADC_DATA_PACKER_2_S00_AXI_BASEADDR
|
||||
#define WAVELENGTH 8192
|
||||
#define TX_BUFFER_BASE XPAR_MIG_7SERIES_0_BASEADDR +0x2000
|
||||
#define WAVE_LENGTH 8192*4
|
||||
|
||||
#define GPIO_INT_ID XPAR_FABRIC_GPIO_0_VEC_ID //PL 端 AXI GPIO 中断 ID
|
||||
#define AXI_GPIO_ID XPAR_AXI_GPIO_0_DEVICE_ID //PL 端 AXI GPIO 器件 ID
|
||||
#define SCUGIC_ID XPAR_SCUGIC_0_DEVICE_ID //中断控制器 ID
|
||||
|
||||
#define FRQHOP_MASK XGPIO_IR_CH1_MASK //通道 1 的位定义
|
||||
|
||||
void AXIGpioInit(void);
|
||||
void ConfigAXIGPIOIntr(void);
|
||||
void axi_gpio_handler(void *CallbackRef);
|
||||
void XScuGicInit(void);
|
||||
void ExceptionInit(void);
|
||||
void frqhop_flag(int frqhop_flag);
|
||||
|
||||
int SpiPsInit(u16 SpiDeviceId);
|
||||
|
||||
int GpioInit(u16 DeviceId);
|
||||
int GpioSetPinDir(u32 Pin,u32 Direction);
|
||||
int GpioWritePin(u32 Pin,u32 data);
|
||||
int GpioReadPin(u32 Pin);
|
||||
|
||||
int peripheral_test(void);
|
||||
|
||||
int cx3e04_write(int addr , int value);
|
||||
int cx3e04_read(int addr);
|
||||
int cx9261a_write(int addr , int value);
|
||||
int cx9261a_read(int addr);
|
||||
|
||||
int SpiPs_write_read(u8 * data,u8 * rx_data);
|
||||
int SpiPs_write_read1(u16 addr,u8 data,u8 * rx_data);
|
||||
int SpiPs_write_read2(u16 addr,u8 data,u8 * rx_data);
|
||||
#define SPI_STACK_LENGTH 65536
|
||||
struct spi_stack {
|
||||
int spi_write_num;
|
||||
u8 recv_buf[SPI_STACK_LENGTH*3];
|
||||
};
|
||||
int spi_stack_in(u8 * data,struct spi_stack * spistack);
|
||||
void spi_stack_out(struct spi_stack * spistack);
|
||||
|
||||
void cx3e04_config(void);
|
||||
void cx9261a_config(void);
|
||||
void DeviceRst(void);
|
||||
|
||||
extern XAxiDma* xAxiDma0Get(void);
|
||||
extern XAxiDma* xAxiDma1Get(void);
|
||||
extern XAxiDma* xAxiDma2Get(void);
|
||||
int XAxiDma_Init(XAxiDma* AxiDma,u16 DeviceId);
|
||||
int XAxiDmaCapture(XAxiDma* AxiDma,u32 data_length);
|
||||
int XAxiDmaCapture2(XAxiDma* AxiDma,u32 data_length);
|
||||
|
||||
int DownloadWave(u8 * data);
|
||||
int SetPacketSize(XAxiDma* AxiDma,u32 length);
|
||||
void dbg_printf( const char8 *ctrl1, ...);
|
||||
void PackerRst(void);
|
||||
|
||||
int rom_read(u8 * data);
|
||||
void download_bin(void);
|
||||
//跳频
|
||||
void frqhop_config(int hop_flag);
|
||||
int PLL_config(u8 pll_index,double pll_frq);
|
||||
void trx_ch_pll_config(u8 pll_index);
|
||||
int pll_frq_caculation_new(double ref,double pll_frq,u8 *reg_data);
|
||||
void PLL_afc(u16 afc_addr,u16 div_addr,u8 pll_div);
|
||||
char divBin(u16 div);
|
||||
+2181
File diff suppressed because it is too large
Load Diff
+546
@@ -0,0 +1,546 @@
|
||||
/**
|
||||
* @file cx9261adriver.h
|
||||
*/
|
||||
|
||||
#ifndef CX9261ADRIVER_CX9261ADRIVER_H
|
||||
#define CX9261ADRIVER_CX9261ADRIVER_H
|
||||
|
||||
#define VERSION 1.10.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
|
||||
+138
@@ -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
|
||||
@@ -0,0 +1,47 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2008 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __MEMORY_CONFIG_H_
|
||||
#define __MEMORY_CONFIG_H_
|
||||
|
||||
struct memory_range_s {
|
||||
char *name;
|
||||
char *ip;
|
||||
unsigned long base;
|
||||
unsigned long size;
|
||||
};
|
||||
|
||||
/* generated memory ranges defined in memory_ranges_g.c */
|
||||
extern struct memory_range_s memory_ranges[];
|
||||
extern int n_memory_ranges;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,38 @@
|
||||
/* This file is automatically generated based on your hardware design. */
|
||||
#include "memory_config.h"
|
||||
|
||||
struct memory_range_s memory_ranges[] = {
|
||||
{
|
||||
"axi_bram_ctrl_0_Mem0",
|
||||
"axi_bram_ctrl_0",
|
||||
0x42000000,
|
||||
32768,
|
||||
},
|
||||
{
|
||||
"axi_bram_ctrl_1_Mem0",
|
||||
"axi_bram_ctrl_1",
|
||||
0x43000000,
|
||||
32768,
|
||||
},
|
||||
{
|
||||
"mig_7series_0_memaddr",
|
||||
"mig_7series_0",
|
||||
0x80000000,
|
||||
1073741824,
|
||||
},
|
||||
{
|
||||
"ps7_ddr_0",
|
||||
"ps7_ddr_0",
|
||||
0x00100000,
|
||||
1072693248,
|
||||
},
|
||||
/* ps7_ram_0 memory will not be tested since application resides in the same memory */
|
||||
{
|
||||
"ps7_ram_1",
|
||||
"ps7_ram_1",
|
||||
0xFFFF0000,
|
||||
65024,
|
||||
},
|
||||
};
|
||||
|
||||
int n_memory_ranges = 5;
|
||||
@@ -0,0 +1,108 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "xparameters.h"
|
||||
#include "xil_types.h"
|
||||
#include "xstatus.h"
|
||||
#include "xil_testmem.h"
|
||||
|
||||
#include "platform.h"
|
||||
#include "memory_config.h"
|
||||
#include "xil_printf.h"
|
||||
|
||||
/*
|
||||
* memory_test.c: Test memory ranges present in the Hardware Design.
|
||||
*
|
||||
* This application runs with D-Caches disabled. As a result cacheline requests
|
||||
* will not be generated.
|
||||
*
|
||||
* For MicroBlaze/PowerPC, the BSP doesn't enable caches and this application
|
||||
* enables only I-Caches. For ARM, the BSP enables caches by default, so this
|
||||
* application disables D-Caches before running memory tests.
|
||||
*/
|
||||
|
||||
void putnum(unsigned int num);
|
||||
|
||||
void test_memory_range(struct memory_range_s *range) {
|
||||
XStatus status;
|
||||
|
||||
/* This application uses print statements instead of xil_printf/printf
|
||||
* to reduce the text size.
|
||||
*
|
||||
* The default linker script generated for this application does not have
|
||||
* heap memory allocated. This implies that this program cannot use any
|
||||
* routines that allocate memory on heap (printf is one such function).
|
||||
* If you'd like to add such functions, then please generate a linker script
|
||||
* that does allocate sufficient heap memory.
|
||||
*/
|
||||
|
||||
print("Testing memory region: "); print(range->name); print("\n\r");
|
||||
print(" Memory Controller: "); print(range->ip); print("\n\r");
|
||||
#ifdef __MICROBLAZE__
|
||||
print(" Base Address: 0x"); putnum(range->base); print("\n\r");
|
||||
print(" Size: 0x"); putnum(range->size); print (" bytes \n\r");
|
||||
#else
|
||||
xil_printf(" Base Address: 0x%lx \n\r",range->base);
|
||||
xil_printf(" Size: 0x%lx bytes \n\r",range->size);
|
||||
#endif
|
||||
|
||||
status = Xil_TestMem32((u32*)range->base, 1024, 0xAAAA5555, XIL_TESTMEM_ALLMEMTESTS);
|
||||
print(" 32-bit test: "); print(status == XST_SUCCESS? "PASSED!":"FAILED!"); print("\n\r");
|
||||
|
||||
status = Xil_TestMem16((u16*)range->base, 2048, 0xAA55, XIL_TESTMEM_ALLMEMTESTS);
|
||||
print(" 16-bit test: "); print(status == XST_SUCCESS? "PASSED!":"FAILED!"); print("\n\r");
|
||||
|
||||
status = Xil_TestMem8((u8*)range->base, 4096, 0xA5, XIL_TESTMEM_ALLMEMTESTS);
|
||||
print(" 8-bit test: "); print(status == XST_SUCCESS? "PASSED!":"FAILED!"); print("\n\r");
|
||||
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int i;
|
||||
|
||||
init_platform();
|
||||
|
||||
print("--Starting Memory Test Application--\n\r");
|
||||
print("NOTE: This application runs with D-Cache disabled.");
|
||||
print("As a result, cacheline requests will not be generated\n\r");
|
||||
|
||||
for (i = 0; i < n_memory_ranges; i++) {
|
||||
test_memory_range(&memory_ranges[i]);
|
||||
}
|
||||
|
||||
print("--Memory Test Application Complete--\n\r");
|
||||
|
||||
cleanup_platform();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "xparameters.h"
|
||||
#include "xil_cache.h"
|
||||
|
||||
#include "platform_config.h"
|
||||
|
||||
#ifdef STDOUT_IS_16550
|
||||
#include "xuartns550_l.h"
|
||||
#endif
|
||||
|
||||
void
|
||||
enable_caches()
|
||||
{
|
||||
#ifdef __PPC__
|
||||
Xil_ICacheEnableRegion(XPAR_CACHEABLE_REGION_MASK);
|
||||
// Do not enable caches for memory tests, this has pros and cons
|
||||
// Pros - If caches are enabled, under certain configurations, there will be very few
|
||||
// transactions to external memory
|
||||
// Con - This might not generate a burst cacheline request
|
||||
// Xil_DCacheEnableRegion(CACHEABLE_REGION_MASK);
|
||||
#elif __MICROBLAZE__
|
||||
#ifdef XPAR_MICROBLAZE_USE_ICACHE
|
||||
Xil_ICacheEnable();
|
||||
#endif
|
||||
#ifdef XPAR_MICROBLAZE_USE_DCACHE
|
||||
// See reason above for not enabling D Cache
|
||||
// Xil_DCacheEnable();
|
||||
#endif
|
||||
#elif __arm__
|
||||
// For ARM, BSP enables caches by default.
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
disable_caches()
|
||||
{
|
||||
Xil_DCacheDisable();
|
||||
Xil_ICacheDisable();
|
||||
}
|
||||
|
||||
void
|
||||
init_platform()
|
||||
{
|
||||
enable_caches();
|
||||
|
||||
#ifdef __arm__
|
||||
// For ARM, BSP enables caches by default. Disable them here.
|
||||
// See reason above for disabling D Cache
|
||||
Xil_DCacheDisable();
|
||||
#endif
|
||||
|
||||
/* if we have a uart 16550, then that needs to be initialized */
|
||||
#ifdef STDOUT_IS_16550
|
||||
XUartNs550_SetBaud(STDOUT_BASEADDR, XPAR_XUARTNS550_CLOCK_HZ, 9600);
|
||||
XUartNs550_SetLineControlReg(STDOUT_BASEADDR, XUN_LCR_8_DATA_BITS);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
cleanup_platform()
|
||||
{
|
||||
disable_caches();
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2008 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __PLATFORM_H_
|
||||
#define __PLATFORM_H_
|
||||
|
||||
#include "platform_config.h"
|
||||
|
||||
void init_platform();
|
||||
void cleanup_platform();
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,4 @@
|
||||
#ifndef __PLATFORM_CONFIG_H_
|
||||
#define __PLATFORM_CONFIG_H_
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user