234 lines
7.8 KiB
C
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;
|
|
} |