adrv9009官方例程_headless.c中jesd_init和xcvr_init阅读理解

JESD_init

首先完成jesd_init
jesd_init代码 以rx_jesd为例

uint32_t rx_lane_rate_khz = rx_div40_rate_hz / 1000 * 40;
	struct jesd204_rx_init rx_jesd_init = {
		"rx_jesd",
		RX_JESD_BASEADDR,
		4,
		32,
		1,
		rx_div40_rate_hz / 1000,
		rx_lane_rate_khz
	};

定义rx_jesd_init,该jesd_rx_init结构如下

struct jesd204_rx_init {
	/** Device Name */
	const char *name;
	/** Base address */
	uint32_t base;
	/** Number of octets per frame (F) */
	uint8_t octets_per_frame;
	/** Number of frames per multi-frame (K) */
	uint16_t frames_per_multiframe;
	/** The JESD204B subclass */
	uint8_t subclass;
	/** Device Clock in KHz for the JESD204 interface */
	uint32_t device_clk_khz;
	/** Lane Clock in KHz */
	uint32_t lane_clk_khz;
};

status = axi_jesd204_rx_init(&rx_jesd, &rx_jesd_init);
再运行axi_jesd204_rx_init,返回状态值提示是否初始化成功

axi_jesd204_rx_read() RX AXI Data Read:

int32_t axi_jesd204_rx_read(struct axi_jesd204_rx *jesd,
			    uint32_t reg_addr, uint32_t *reg_val)

kimi回答axi_jesd204_rx_init作用:

函数定义:int32_t axi_jesd204_rx_init 接受两个参数,一个是指向 axi_jesd204_rx 指针的指针 jesd204,另一个是一个包含初始化参数的结构体 init。

声明本地变量:struct axi_jesd204_rx *jesd 是指向 axi_jesd204_rx 结构体的指针,uint32_t synth_1、magic、status 和 tmp 是无符号32位整数变量。

分配内存:使用 malloc 为 jesd 分配内存空间,如果分配失败则返回 -1。

复制初始化参数:将 init 结构体中的成员复制到 jesd 结构体中。

读取寄存器:通过 axi_jesd204_rx_read 函数读取JESD204接收器的寄存器值,检查设备标识符 magic 是否正确,如果不正确则打印错误信息并跳转到 err 标签,释放内存并返回 -1。

检查版本:读取并检查设备的版本号,如果版本号不是1.x.x,则打印错误信息并跳转到 err。

读取其他配置信息:读取通道数、数据路径宽度等配置信息,并根据这些信息设置 jesd 结构体的相应成员。

检查编码器类型:根据读取到的编码器类型设置 jesd 结构体的 encoder 成员,如果编码器类型未知或超出范围,则跳转到 err。

设置配置:将初始化参数中的配置复制到 jesd 结构体的 config 成员中。

禁用通道时钟:调用 axi_jesd204_rx_lane_clk_disable 函数禁用通道时钟。

应用配置:调用 axi_jesd204_rx_apply_config_legacy 函数应用配置,如果状态码不是0,则跳转到 err。

设置返回值:如果一切顺利,将 jesd 指针赋值给 *jesd204 并返回 0。

错误处理:如果任何步骤失败,跳转到 err 标签,释放之前分配的内存并返回 -1。

XCVR理解

struct adxcvr_init rx_adxcvr_init = {
		.name = "rx_adxcvr",
		.base = RX_XCVR_BASEADDR,
		.sys_clk_sel = ADXCVR_SYS_CLK_CPLL,
		.out_clk_sel = ADXCVR_REFCLK,
		.lpm_enable = 1,
		.lane_rate_khz = rx_lane_rate_khz,
		.ref_rate_khz = device_clock,
status = adxcvr_init(&rx_adxcvr, &rx_adxcvr_init);
status = adxcvr_clk_enable(rx_adxcvr);
	};

XCVR_init KIMI读:
函数定义:int32_t adxcvr_init 接受两个参数,一个是指向 adxcvr 指针的指针 ad_xcvr,另一个是一个包含初始化参数的结构体 init。

声明本地变量:struct adxcvr *xcvr 是指向 adxcvr 结构体的指针,uint32_t synth_conf 和 xcvr_type 是无符号32位整数变量,uint32_t i 是循环计数器,int32_t ret 是函数返回值。

分配内存:使用 calloc 为 xcvr 分配内存空间并初始化为0,如果分配失败则返回 -1。

复制初始化参数:将 init 结构体中的成员复制到 xcvr 结构体中。

读取寄存器:通过 adxcvr_read 函数读取 ADXCVR_REG_SYNTH 寄存器的值,并根据寄存器的位字段设置 xcvr 结构体的 tx_enable、num_lanes 和 qpll_enable 成员。

检查 QPLL 配置:如果 QPLL 未启用且系统时钟选择不是 CPLL,则打印一条信息。

读取 XCVR 类型:从 synth_conf 中提取 XCVR 类型。

读取版本信息:读取 AXI_REG_VERSION 寄存器的值,如果版本大于0x10,则调用 adxcvr_get_info 函数。

根据版本信息设置 XCVR 类型:如果版本是旧版本,则根据 xcvr_type 设置 xcvr 结构体的 xlx_xcvr.type 成员。如果是新版本,则直接使用 xcvr_type。在这里选了GTX2/GTH3/GTH4/GTY4

检查 XCVR 类型:如果 xcvr 类型不在已知列表中,则打印错误信息并跳转到 err。

设置编码和参考时钟精度:设置 xcvr 结构体的 xlx_xcvr.encoding ,选择8B10B编码方式,和 xlx_xcvr.refclk_ppm 成员。定义REFCLK_PPM?

重置 XCVR:通过 adxcvr_write 函数写入 ADXCVR_REG_RESETN 寄存器以重置 XCVR。

设置控制寄存器:根据 xcvr 结构体的成员设置 ADXCVR_REG_CONTROL 寄存器。

设置 AD 转换器结构体指针:将 xcvr 指针赋值给 xcvr->xlx_xcvr.ad_xcvr。

配置 LPM/DFE 模式:如果 tx_enable 为假且 lpm_enable 为真,则为每个通道配置 LPM/DFE 模式。
LPM(低功耗模式):

LPM 是一种节能模式,用于在不需要高速数据传输时降低设备的功耗。
在通信设备中,LPM 可以减少在非活动或低负载期间的能耗。
LPM 通常与时钟门控(clock gating)和其他节能技术结合使用,以进一步提高能效。
DFE(数字前向均衡器):

DFE 是一种用于补偿信号在传输介质中遇到的干扰和失真的数字信号处理技术。
它通过分析接收到的信号并应用特定的算法来预测和抵消由于色散、反射或其他效应引起的信号失真。
DFE 通常用于高速串行通信链路,如光纤通信、高速以太网等,以提高信号的完整性和链路的性能。
在高速串行通信系统中,LPM 和 DFE 可以结合使用,以实现在保持高性能的同时降低功耗。

设置时钟速率:如果提供了通道速率和参考速率,则调用 adxcvr_clk_set_rate 函数设置时钟速率,如果失败则跳转到 err。

设置返回值:如果一切顺利,将 xcvr 指针赋值给 *ad_xcvr 并返回 0。

错误处理:如果任何步骤失败,跳转到 err 标签,释放之前分配的内存并返回 -1

adxcvr_clk_enable

函数定义:int adxcvr_clk_enable(struct adxcvr *xcvr) 接受一个指向 adxcvr 结构体的指针 xcvr。

声明本地变量:int ret 是函数返回值,retry 是重试次数,status 是状态寄存器的值,bufstatus_err 用于标记缓冲区状态错误。

调试打印:使用 pr_debug 打印当前函数名和 xcvr 的传输方向(TX 或 RX)。

重置 adxcvr:调用 adxcvr_reset 函数重置 xcvr,如果重置失败则直接返回错误码。

版本检查:如果 xcvr 的版本号大于或等于17.5a,执行以下操作。

重置循环:使用 do-while 循环进行重置操作和状态检查,最多重试10次。

写入重置寄存器:首先写入 ADXCVR_REG_RESETN 寄存器以重置缓冲区状态,然后只重置 xcvr。

延迟:使用 no_os_mdelay 函数延迟1毫秒,以确保重置操作完成。

读取状态:读取 ADXCVR_REG_STATUS 寄存器的值到 status 变量。

检查缓冲区错误:如果状态寄存器中的 ADXCVR_BUFSTATUS_UNDERFLOW 或 ADXCVR_BUFSTATUS_OVERFLOW 位被设置,则认为发生了缓冲区错误。

处理缓冲区错误:如果检测到缓冲区错误,则再次调用 adxcvr_reset 函数尝试恢复,如果重置失败则返回错误码。

错误打印:如果状态寄存器指示缓冲区下溢或溢出,则使用 pr_err 打印错误信息。

函数返回:最后,函数返回 ret,即 adxcvr_reset 函数的返回值。

3

错误修改

在我的串口打印程序中会出现:
CPLL RX buffer underflow error, status: 0x61
0x61错误即?
-"buffer underflow"指的是数据缓冲区中的数据被读取得太快,以至于缓冲区中没有足够的数据供进一步处理。这种情况通常发生在数据产生速率低于数据消费速率时,可能导致数据丢失或处理错误。
#define ADXCVR_REG_STATUS 0x0014
寄存器地址是这个

目前还不知道怎么查看这个0x61错误怎么改

  • 10
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值