Files
CX9261API-C/ld_test.c
T
2024-10-27 21:53:10 +08:00

234 lines
7.8 KiB
C

#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdint.h>
#include "cx9261adriver_c.h"
#define max(x, y) ((x >= y) ? x : y)
// --- Dummy systemcall implementation
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
int _write(int file, char *ptr, int len)
{
return len;
}
int _read(int file, char *ptr, int len)
{
return 0;
}
int _close(int file)
{
return -1; // 模拟文件关闭失败
}
int _fstat(int file, struct stat *st)
{
st->st_mode = S_IFCHR;
return 0;
}
int _lseek(int file, int ptr, int dir)
{
return 0;
}
int _isatty(int file)
{
return 0;
}
int _kill(int pid, int sig)
{
errno = EINVAL;
return -1;
}
int _getpid(void)
{
return 1;
}
#pragma GCC diagnostic pop
// ---
void udelay(uint32_t cnt)
{
while (cnt--)
;
}
void CX9261A_Log(const char *msg)
{
printf("[CX9261A] %s\n", msg);
}
void CX9261A_spiWrite(int address, int value)
{
printf("[CX9261A] spi write 0x%08X = 0x%08X\n", address, value);
}
int CX9261A_spiRead(int address)
{
printf("[CX9261A] spi read 0x%08X\n", address);
return 0xFFFFF;
}
void CX9261A_mdelay(double ms)
{
udelay((uint32_t)ms * 1e3);
}
void CX9261A_setPin(int pin, int value)
{
printf("[CX9261A] set 0x%08X = 0x%08X\n", pin, value);
return;
}
CX9261A_CX9261AConfiguration 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},
// 发射模式电源管理
.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模式电源管理
.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},
.powerMode = CX9261A_PWM_Receive,
},
// 接口模式
.interface = {.workMode = CX9261A_WKM_Rx,
.trMode = CX9261A_TRM_R1T1,
.portMode = CX9261A_PORTM_Single,
.ioMode = CX9261A_IOM_CMOS},
// 时钟相关
.clock = {.ref = 125,
.adc = 64,
.refDiv = 2,
.bbUseIntDiv = false,
.refDoubler = false},
// 本振相关
// 本振来源
.pllSource = {.rxUseExt = false,
.txUseExt = false,
.rx1Source = CX9261A_LOSRC_Pll1,
.rx2Source = CX9261A_LOSRC_Pll1,
.rx3Source = CX9261A_LOSRC_Off,
.tx1Source = CX9261A_LOSRC_Off,
.tx2Source = CX9261A_LOSRC_Off},
// 本振频率 注意:使用的所有PLL,频率必须设为正数
.pllFreq = {.pll1Freq = 5800,
.pll2Freq = 5800,
.pll3Freq = 800,
.pll4Freq = 900,
.pll5Freq = 1000},
// Rx通道 注意:tia推荐配置为6 Mixer为三个通道共用同一个寄存器
.rx1Config = {.bandwidth = 32, .tia = 6, .mixer = 31},
.rx2Config = {.bandwidth = 32, .tia = 6, .mixer = 31},
.rx3Config = {.bandwidth = 32, .tia = 6, .mixer = 31},
// Tx通道
.tx1Config = {.bandwidth = 20, .mixer = 63},
.tx2Config = {.bandwidth = 20, .mixer = 63},
// 接收滤波器
.rxFilters = {.fir = 0, .hbf1 = 0, .hbf2 = 0, .hbf3 = 0, .cic = 0},
// 发射滤波器
.txFilters = {.fir = 0, .hbf1 = 2, .hbf2 = 2, .hbf3 = 0, .cic = 0},
// Rx NCO
.rxNco = {.rxUseBist = false,
.rxNCOBypass = true,
.rxNCOUpward = true,
.rxNCOMaster = true,
.rxNCOFreq = 0},
// Tx NCO
.txNco = {.txUseBist = false, .txNCOFreq = 0},
// AGC 注意:mode = 0表示关闭AGC,此时其他的参数可以不配置
// 校准
.calib = {.calibDC = true,
.dcCalibMethod = CX9261A_DCCALM_Tracking,
.dcTrackingLength = 16384,
.dcHighPassFactor = 8191,
.rx1CalibPll = CX9261A_LOSRC_Pll1 | CX9261A_LOSRC_Pll2,
.rx2CalibPll = CX9261A_LOSRC_Pll1 | CX9261A_LOSRC_Pll2,
.rx3CalibPll = CX9261A_LOSRC_Pll5,
.tx1CalibPll = 0,
.tx2CalibPll = 0,
.rxMethod = CX9261A_CALM_MultiPoints,
.txMethod = CX9261A_CALM_Bisec,
.f0 = 4,
.rxMultiPoints = {2200, 2400, 2600, 2800, 3000, 3200, 3400,
3600, 3800, 4000, 4200, 4400, 4600, 4800,
5000, 5200, 5400, 5600, 5800, 6000}},
.agc = {.mode = 0},
.tempComp = CX9261A_TEMPCP_Band
};
int main()
{
// 绑定函数
CX9261A_setLoggingFunc(CX9261A_Log);
CX9261A_setWriteSpiFunc(CX9261A_spiWrite);
CX9261A_setReadSpiFunc(CX9261A_spiRead);
CX9261A_setPauseFunc(CX9261A_mdelay);
CX9261A_setSetPinFunc(CX9261A_setPin);
// 开始配置芯片
CX9261A_initialChip(); // 最开始需要调用此函数
CX9261A_initialPowerConfig(&configuration);
// 配置温补
CX9261A_configTemperatureCompensation(configuration.tempComp);
// 不需要自定义电源管理时,这部分代码可以省略
CX9261A_configPowerPins(&(configuration.powerManagement.rxPower), CX9261A_PWM_Receive);
CX9261A_configPowerPins(&(configuration.powerManagement.txPower), CX9261A_PWM_Transmit);
CX9261A_configPowerPins(&(configuration.powerManagement.fddPower), CX9261A_PWM_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_RXCH_Rx1);
CX9261A_configRxChannel(&(configuration.rx2Config), CX9261A_RXCH_Rx2);
CX9261A_configRxChannel(&(configuration.rx3Config), CX9261A_RXCH_Rx3);
// 配置Tx通道
CX9261A_configTxChannelFrequency(configuration.pllFreq.pll1Freq, CX9261A_TXCH_Tx1);
CX9261A_configTxChannelFrequency(configuration.pllFreq.pll2Freq, CX9261A_TXCH_Tx2);
CX9261A_configTxChannel(&(configuration.tx1Config), CX9261A_TXCH_Tx1);
CX9261A_configTxChannel(&(configuration.tx2Config), CX9261A_TXCH_Tx2);
// 配置滤波器
CX9261A_configRxFilters(&(configuration.rxFilters));
CX9261A_configTxFilters(&(configuration.txFilters));
// 配置NCO
CX9261A_configRxNco(&(configuration.rxNco), configuration.clock.adc);
int filters = max(configuration.rxFilters.fir, 1) * max(configuration.rxFilters.hbf3, 1) *
max(configuration.rxFilters.hbf2, 1) *
max(configuration.rxFilters.hbf1, 1) * max(configuration.rxFilters.cic, 1);
CX9261A_configTxNco(&(configuration.txNco), configuration.clock.adc / filters);
// 配置AGC
CX9261A_configAGC(&(configuration.agc));
// 切换到休眠模式
CX9261A_configPowerMode(CX9261A_PWM_Sleep);
udelay(1000 * 1000);
// 切换到校准模式
CX9261A_configPowerMode(CX9261A_PWM_Calib);
udelay(100 * 1000);
// 锁定BBPLL
CX9261A_afcBBPll();
// 配置校准
CX9261A_configADCCalib(configuration.clock.adc);
CX9261A_configFlashCalib();
CX9261A_configDcCalib(&(configuration.calib));
CX9261A_configQecCalib(&configuration);
CX9261A_loadRxCalibPredis(0, CX9261A_RXCH_Rx1, CX9261A_LOSRC_Pll1);
CX9261A_loadRxCalibPredis(0, CX9261A_RXCH_Rx2, CX9261A_LOSRC_Pll1);
// 配置接口
CX9261A_configInterface(&(configuration.interface));
// 配置FPGA接口相关 此为示例,仅适用于Demo工程,用户应根据实际情况进行配置
CX9261A_configFPGA(&(configuration.interface));
// 锁定PLL1
CX9261A_afcPll1();
// 锁定PLL2
CX9261A_afcPll2();
return 0;
}