Files
smod_atsc_app/atsc_app/adrv9009/jesd204b_config.c
T

428 lines
13 KiB
C
Executable File

#include <unistd.h>
#include <stdio.h>
//#include"../common.h"
//#include"../fpga.h"
#include "../inc/i2c_drv.h"
#include "../inc/isys_config.h"
/*
//for tx0
#define TX0_CFG_ENABLE_REG 0x76 //bit4->rd bit5->wr
#define TX0_CFG_ADDR_REG 0x74
#define TX0_CFG_WR_DATA_REG 0x75
#define TX0_CFG_RD_DATA_REG 0xb6
#define TX0_CFG_RD_UPDATA_FLAG_REG 0xb3 //bit2 is avalid
//for fb0
#define FB0_CFG_ENABLE_REG 0x76 //bit2->rd bit3->wr
#define FB0_CFG_ADDR_REG 0x72
#define FB0_CFG_WR_DATA_REG 0x73
#define FB0_CFG_RD_DATA_REG 0xb5
#define FB0_CFG_RD_UPDATA_FLAG_REG 0xb3 //bit1 is avalid
//for rx0
#define RX0_CFG_ENABLE_REG 0x76 //bit0->rd bit1->wr
#define RX0_CFG_ADDR_REG 0x70
#define RX0_CFG_WR_DATA_REG 0x71
#define RX0_CFG_RD_DATA_REG 0xb4
#define RX0_CFG_RD_UPDATA_FLAG_REG 0xb3 //bit0 is avalid
*/
//for tx0/fb0/rx0 (共享 0xB1~0xB8 I2C 寄存器)
#define TX0_CFG_ENABLE_REG 0xB5 //bit1->rd bit2->wr
#define TX0_CFG_ADDR_H_REG 0xB7
#define TX0_CFG_ADDR_L_REG 0xB6
#define TX0_CFG_WR_DATA_REG 0xB8
#define TX0_CFG_RD_DATA_REG 0xb6
#define TX0_CFG_RD_UPDATA_FLAG_REG 0xb3 //bit2 is avalid
//for fb0 (registers from Task11.md §3.1 — FPGA I2C->JESD AXI bridge)
#define FB0_CFG_ENABLE_REG 0xBC // bit0->rd bit1->wr
#define FB0_CFG_ADDR_L_REG 0xBD // addr[7:0]
#define FB0_CFG_ADDR_H_REG 0xBE // addr[11:8] (仅低4位有效)
#define FB0_CFG_WR_DATA_REG 0xBF // write data[7:0]
#define FB0_CFG_MON_REG 0xBB // monitor: bit2=rd_update, bit1=fb_sync, bit0=fb_tvalid
#define FB0_CFG_RD_DATA0_REG 0xC0 // read data[7:0]
#define FB0_CFG_RD_DATA1_REG 0xC1 // read data[15:8]
#define FB0_CFG_RD_DATA2_REG 0xC2 // read data[23:16]
#define FB0_CFG_RD_DATA3_REG 0xC3 // read data[31:24]
//for rx0
#define RX0_CFG_ENABLE_REG 0xB5 //bit1->rd bit2->wr
#define RX0_CFG_ADDR_REG 0x70
#define RX0_CFG_WR_DATA_REG 0x71
#define RX0_CFG_RD_DATA_REG 0xb4
#define RX0_CFG_RD_UPDATA_FLAG_REG 0xb3 //bit2 is avalid
//----------------------------------------------------------
//for tx1/fb1/rx1 (共享 0x50~0x5F I2C 寄存器)
#define TX1_CFG_ENABLE_REG 0x56 //bit1->rd bit2->wr
#define TX1_CFG_ADDR_REG 0x54
#define TX1_CFG_WR_DATA_REG 0x55
#define TX1_CFG_RD_DATA_REG 0xc6
#define TX1_CFG_RD_UPDATA_FLAG_REG 0xc3 //bit2 is avalid
//for fb1
#define FB1_CFG_ENABLE_REG 0x56 //bit1->rd bit2->wr
#define FB1_CFG_ADDR_REG 0x52
#define FB1_CFG_WR_DATA_REG 0x53
#define FB1_CFG_RD_DATA_REG 0xc5
#define FB1_CFG_RD_UPDATA_FLAG_REG 0xc3 //bit2 is avalid
//for rx1
#define RX1_CFG_ENABLE_REG 0x56 //bit1->rd bit2->wr
#define RX1_CFG_ADDR_REG 0x50
#define RX1_CFG_WR_DATA_REG 0x51
#define RX1_CFG_RD_DATA_REG 0xc4
#define RX1_CFG_RD_UPDATA_FLAG_REG 0xc3 //bit2 is avalid
void jesd204b_rd_test(void)
{
printf(" >>jesd204b_rd_test\n");
uint32 data[10];
fpga_read_axi0(0xB1,&data[0],1);
fpga_read_axi0(0xB2,&data[1],1);
fpga_read_axi0(0xB3,&data[2],1);
fpga_read_axi0(0xB4,&data[3],1);
fpga_read_axi0(0xB5,&data[4],1);
fpga_read_axi0(0xB6,&data[5],1);
fpga_read_axi0(0xB7,&data[6],1);
fpga_read_axi0(0xB8,&data[7],1);
printf(" rd [B1=0x%x B2=0x%x B3=0x%x B4=0x%x] [B7=0x%x B6=0x%x B8=0x%x B5=0x%x] \n",
data[0],data[1],data[2],data[3], data[6],data[5],data[7],data[4]
);
usleep(1000);
}
void jesd204b_tx0_wr(u32 addr,u32 dat)
{
printf(" >>W [jesd_wr_tx0] addr=0x%x data=0x%x\n", addr, dat);
fpga_write_axi0(TX0_CFG_ADDR_H_REG,(addr>>8)&0xff,1);//B7
fpga_write_axi0(TX0_CFG_ADDR_L_REG,addr&0xff,1);//B6
fpga_write_axi0(TX0_CFG_WR_DATA_REG,dat,1);//B8
fpga_write_axi0(TX0_CFG_ENABLE_REG,0x0,1);//B5
fpga_write_axi0(TX0_CFG_ENABLE_REG,0x04,1);
fpga_write_axi0(TX0_CFG_ENABLE_REG,0x0,1);
usleep(1000);
}
//----------------------------------------------------------------------------
void jesd204b_fb0_wr(u32 addr,u32 dat) //验证OK
{
printf(" >>W [jesd_wr_fb0] addr=0x%x data=0x%x\n", addr, dat);
/* FB0 bridge: 写时序 (Task11 §3.2)
1. 写 FB0_CFG_ADDR_L_REG = addr[7:0] (0xBD)
2. 写 FB0_CFG_ADDR_H_REG = addr[11:8] (0xBE)
3. 写 FB0_CFG_WR_DATA_REG = dat[7:0] (0xBF, 仅8-bit 宽)
4. 清 FB0_CFG_ENABLE_REG (0xBC)
5. 置位 bit1 (wr) (0xBC = 0x02)
6. 清 FB0_CFG_ENABLE_REG (0xBC = 0x00)
*/
fpga_write_axi0(FB0_CFG_ADDR_L_REG, addr & 0xFF, 1);
fpga_write_axi0(FB0_CFG_ADDR_H_REG, (addr >> 8) & 0x0F, 1);
fpga_write_axi0(FB0_CFG_WR_DATA_REG, dat & 0xFF, 1);
fpga_write_axi0(FB0_CFG_ENABLE_REG, 0x00, 1);
fpga_write_axi0(FB0_CFG_ENABLE_REG, 0x02, 1); // bit1 = wr
fpga_write_axi0(FB0_CFG_ENABLE_REG, 0x00, 1);
usleep(1000);
}
u32 jesd204b_fb0_rd(u32 addr) //验证OK
{
u32 data = 0;
u32 mon = 0;
int timeout = 10;
/* FB0 bridge: 读时序 (Task11 §3.2)
1. 写 FB0_CFG_ADDR_L_REG = addr[7:0] (0xBD)
2. 写 FB0_CFG_ADDR_H_REG = addr[11:8] (0xBE)
3. 清 FB0_CFG_ENABLE_REG (0xBC)
4. 置位 bit0 (rd) (0xBC = 0x01)
5. 清 FB0_CFG_ENABLE_REG (0xBC = 0x00)
6. 等待 ~1ms
7. 轮询 FB0_CFG_MON_REG bit2 (0xBB), 超时退出
8. 读 0xC0~0xC3 组合为 32-bit (小端序)
*/
fpga_write_axi0(FB0_CFG_ADDR_L_REG, addr & 0xFF, 1);
fpga_write_axi0(FB0_CFG_ADDR_H_REG, (addr >> 8) & 0x0F, 1);
fpga_write_axi0(FB0_CFG_ENABLE_REG, 0x00, 1);
fpga_write_axi0(FB0_CFG_ENABLE_REG, 0x01, 1); // bit0 = rd
fpga_write_axi0(FB0_CFG_ENABLE_REG, 0x00, 1);
usleep(1000);
do {
fpga_read_axi0(FB0_CFG_MON_REG, &mon, 1);
if (mon & 0x04)
break;
usleep(1000);
} while (--timeout > 0);
if (timeout <= 0) {
printf(" >>R [jesd_rd_fb0] addr=0x%x TIMEOUT\n", addr);
return 0xFFFFFFFF;
}
/* 读 4 字节并组合为小端序 32-bit 数据 */
{
u32 tmp;
u8 c0, c1, c2, c3;
fpga_read_axi0(FB0_CFG_RD_DATA0_REG, &tmp, 1); c0 = tmp & 0xFF;
fpga_read_axi0(FB0_CFG_RD_DATA1_REG, &tmp, 1); c1 = tmp & 0xFF;
fpga_read_axi0(FB0_CFG_RD_DATA2_REG, &tmp, 1); c2 = tmp & 0xFF;
fpga_read_axi0(FB0_CFG_RD_DATA3_REG, &tmp, 1); c3 = tmp & 0xFF;
data = ((u32)c3 << 24) | ((u32)c2 << 16) | ((u32)c1 << 8) | c0;
}
printf(" >>R [jesd_rd_fb0] addr=0x%x data=0x%08x\n", addr, data);
return data;
}
void jesd204b_rx0_wr(u32 addr,u32 dat)
{
// printf(" >>W [jesd_rx_tx0] addr=0x%x data=0x%x\n", addr, dat);
/*fpga_write_axi0(RX0_CFG_ADDR_REG,addr,1);
fpga_write_axi0(RX0_CFG_WR_DATA_REG,dat,1);
fpga_write_axi0(RX0_CFG_ENABLE_REG,0x0,1);
fpga_write_axi0(RX0_CFG_ENABLE_REG,0x04,1);
fpga_write_axi0(RX0_CFG_ENABLE_REG,0x0,1);
usleep(1000);*/
}
void jesd204b_tx1_wr(u32 addr,u32 dat)
{
// printf(" >>W [jesd_wr_tx1] addr=0x%x data=0x%x\n", addr, dat);
/*fpga_write_axi0(TX1_CFG_ADDR_REG,addr,1);
fpga_write_axi0(TX1_CFG_WR_DATA_REG,dat,1);
fpga_write_axi0(TX1_CFG_ENABLE_REG,0x0,1);
fpga_write_axi0(TX1_CFG_ENABLE_REG,0x04,1);
fpga_write_axi0(TX1_CFG_ENABLE_REG,0x0,1);
usleep(1000);*/
}
void jesd204b_fb1_wr(u32 addr,u32 dat)
{
// printf(" >>W [jesd_wr_fb1] addr=0x%x data=0x%x\n", addr, dat);
/*fpga_write_axi0(FB1_CFG_ADDR_REG,addr,1);
fpga_write_axi0(FB1_CFG_WR_DATA_REG,dat,1);
fpga_write_axi0(FB1_CFG_ENABLE_REG,0x0,1);
fpga_write_axi0(FB1_CFG_ENABLE_REG,0x04,1);
fpga_write_axi0(FB1_CFG_ENABLE_REG,0x0,1);
usleep(1000);*/
}
void jesd204b_rx1_wr(u32 addr,u32 dat)
{
// printf(" >>W [jesd_wr_rx1] addr=0x%x data=0x%x\n", addr, dat);
/*fpga_write_axi0(RX1_CFG_ADDR_REG,addr,1);
fpga_write_axi0(RX1_CFG_WR_DATA_REG,dat,1);
fpga_write_axi0(RX1_CFG_ENABLE_REG,0x0,1);
fpga_write_axi0(RX1_CFG_ENABLE_REG,0x04,1);
fpga_write_axi0(RX1_CFG_ENABLE_REG,0x0,1);
usleep(1000);*/
}
void jesd204b_tx0_cfg(void)
{
// printf("jesd204b_tx0_cfg start...\n");
//initial
fpga_write_axi0(TX0_CFG_ENABLE_REG,0x0,1);
fpga_write_axi0(TX0_CFG_ADDR_H_REG,0x0,1);
fpga_write_axi0(TX0_CFG_ADDR_L_REG,0x0,1);
fpga_write_axi0(TX0_CFG_WR_DATA_REG,0x0,1);
jesd204b_tx0_wr(0x04,0x01);
jesd204b_tx0_wr(0x08,0x01);
jesd204b_tx0_wr(0x0c,0x0);
jesd204b_tx0_wr(0x10,0x00); /* PR06-2: SYSREF handling OFF (SMOD board has NO SYSREF wired) */
jesd204b_tx0_wr(0x14,0x03);
jesd204b_tx0_wr(0x18,0x0);
jesd204b_tx0_wr(0x20,0x01);
jesd204b_tx0_wr(0x24,0x1f);
jesd204b_tx0_wr(0x28,0x03); /* PR06-2: lanes-in-use mask = 2 lanes (was 0xf) */
jesd204b_tx0_wr(0x2c,0x00); /* PR06-2: Subclass 0 (was 1) - no SYSREF -> align on SYNC~/ILAS only, avoids divergent LMFC phase -> fixes TX no-RF at mixed 60/120/120 rates */
jesd204b_tx0_wr(0x80c,0x01000a55);
jesd204b_tx0_wr(0x810,0x000f0d03);
jesd204b_tx0_wr(0x814,0x0);
jesd204b_tx0_wr(0x818,0x0);
jesd204b_tx0_wr(0x81c,0x0);
printf("jesd204b_tx0_cfg done.\n");
}
void jesd204b_fb0_cfg(void)
{
printf("jesd204b_fb0_cfg start...\n");
/* PR06-2 ORx-only: o_fb 核走 IP 默认(F=2/2lane) 匹配 ADRV framerB(M=2/2lane/120M), 不写寄存器 */
printf("jesd204b_fb0_cfg done.\n");
}
void jesd204b_rx0_cfg(void)
{
printf("jesd204b_rx0_cfg start...\n");
//PR06-2: 取消注释并配 RX0(framerA/RX1) 核为 subclass 0 匹配 ADRV framerA(M=4/F=4/2lane) + 无SYSREF
fpga_write_axi0(RX0_CFG_ENABLE_REG,0x0,1);
fpga_write_axi0(RX0_CFG_ADDR_REG,0x0,1);
fpga_write_axi0(RX0_CFG_WR_DATA_REG,0x0,1);
jesd204b_rx0_wr(0x04,0x01);
jesd204b_rx0_wr(0x08,0x01);
jesd204b_rx0_wr(0x0C,0x0);
jesd204b_rx0_wr(0x10,0x00); /* PR06-2: SYSREF off */
jesd204b_rx0_wr(0x18,0x0);
jesd204b_rx0_wr(0x20,0x03); /* F-1=3 -> F=4 */
jesd204b_rx0_wr(0x24,0x1f); /* K-1=31 -> K=32 */
jesd204b_rx0_wr(0x28,0x03); /* PR06-2 ORx-only: 2 lanes (回退, o_rx核未用) */
jesd204b_rx0_wr(0x2c,0x00); /* PR06-2: Subclass 0 (无SYSREF) */
jesd204b_rx0_wr(0x30,0x0);
jesd204b_rx0_wr(0x34,0x0);
printf("jesd204b_rx0_cfg done\n");
}
void jesd204b_tx1_cfg(void)
{
//initial
/*fpga_write_axi0(TX1_CFG_ENABLE_REG,0x0,1);
fpga_write_axi0(TX1_CFG_ADDR_REG,0x0,1);
fpga_write_axi0(TX1_CFG_WR_DATA_REG,0x0,1);
jesd204b_tx1_wr(0x04,0x01);
jesd204b_tx1_wr(0x08,0x01);
jesd204b_tx1_wr(0x0c,0x0);
jesd204b_tx1_wr(0x10,0x01);
jesd204b_tx1_wr(0x14,0x03);
jesd204b_tx1_wr(0x18,0x0);
jesd204b_tx1_wr(0x20,0x01);
jesd204b_tx1_wr(0x24,0x1f);
jesd204b_tx1_wr(0x28,0x0f);
jesd204b_tx1_wr(0x2c,0x01);
jesd204b_tx1_wr(0x80c,0x01000a55);
jesd204b_tx1_wr(0x810,0x000f0d03);
jesd204b_tx1_wr(0x814,0x0);
jesd204b_tx1_wr(0x818,0x0);
jesd204b_tx1_wr(0x81c,0x0);*/
}
void jesd204b_fb1_cfg(void)
{
//initial
/*fpga_write_axi0(FB1_CFG_ENABLE_REG,0x0,1);
fpga_write_axi0(FB1_CFG_ADDR_REG,0x0,1);
fpga_write_axi0(FB1_CFG_WR_DATA_REG,0x0,1);
jesd204b_fb1_wr(0x04,0x01);
jesd204b_fb1_wr(0x08,0x01);
jesd204b_fb1_wr(0x0C,0x0);
jesd204b_fb1_wr(0x10,0x01);
jesd204b_fb1_wr(0x18,0x0);
jesd204b_fb1_wr(0x20,0x01);
jesd204b_fb1_wr(0x24,0x1f);
jesd204b_fb1_wr(0x28,0x03);
jesd204b_fb1_wr(0x2c,0x01);
jesd204b_fb1_wr(0x30,0x0);
jesd204b_fb1_wr(0x34,0x0);*/
}
void jesd204b_rx1_cfg(void)
{
//initial
/*fpga_write_axi0(RX1_CFG_ENABLE_REG,0x0,1);
fpga_write_axi0(RX1_CFG_ADDR_REG,0x0,1);
fpga_write_axi0(RX1_CFG_WR_DATA_REG,0x0,1);
jesd204b_rx1_wr(0x04,0x01);
jesd204b_rx1_wr(0x08,0x01);
jesd204b_rx1_wr(0x0C,0x0);
jesd204b_rx1_wr(0x10,0x01);
jesd204b_rx1_wr(0x18,0x0);
jesd204b_rx1_wr(0x20,0x03);
jesd204b_rx1_wr(0x24,0x1f);
jesd204b_rx1_wr(0x28,0x03);
jesd204b_rx1_wr(0x2c,0x01);
jesd204b_rx1_wr(0x30,0x0);
jesd204b_rx1_wr(0x34,0x0);*/
}
/*
//add 260427
//0xB1 — JESD_CTRL(链路复位控制)
bit 名称 默认 说明
7 RX_GT_RST1 0 RX GT 复位通道 1(写 1 复位,写 0 释放)
6 RX_GT_RST0 0 RX GT 复位通道 0(写 1 复位,写 0 释放)
5 TX_GT_RST 0 TX GT(收发器)复位(写 1 复位,写 0 释放)
4 FBRX_RST 0 Feedback RX 链路复位(写 1 复位,写 0 释放)
3 RX_RST 0 RX 链路复位(写 1 复位,写 0 释放)
2 TX_RST 0 TX 链路复位(写 1 复位,写 0 释放)
1 PHY_RST 0 PHY 全局复位(写 1 复位,写 0 释放)
0 AXI_RST 0 AXI 总线复位(写 1 复位,写 0 释放)
典型复位序列(JESD 链路重新初始化):
1. 写 0xB1 = 0xFF // 全部复位
2. 延时 ≥ 1ms
3. 写 0xB1 = 0x00 // 释放所有复位
4. 等待 0xB4[0] = 1 // 轮询 TX 就绪
*/
/**
* @brief 执行 JESD204B 链路软复位序列
* @note 对应寄存器 0xB1 JESD_CTRL
*/
void jesd204b_reset_add(void)
{
uint8_t status = 0;
int timeout = 10000; // 防止死循环的超时计数
// 1. 写 0xB1 = 0xFF -> 全部复位
// 注意:这里假设 fpga_byte_write 的参数顺序是 (基地址, 偏移地址, 数据)
// 原代码中的 (addr)&0xff 看起来像是笔误,这里修正为直接写入 0xFF
fpga_byte_write(JESD_SEG_ADDR, 0xB1, 0xFF);
// 2. 延时 ≥ 1ms
// 根据你的系统环境选择延时函数,如 usleep, delay_ms 等
usleep(2000); // 建议稍微多给一点余量,这里延时 2ms
// 3. 写 0xB1 = 0x00 -> 释放所有复位
fpga_byte_write(JESD_SEG_ADDR, 0xB1, 0x00);
// 4. 等待 0xB4[0] = 1 -> 轮询 TX 就绪
// 假设 0xB4 是状态寄存器,Bit 0 为 1 表示 TX 准备好
do {
status = fpga_byte_read(JESD_SEG_ADDR, 0xB4);
timeout--;
usleep(10);
} while (((status & 0x01) == 0) && (timeout > 0));
if (timeout <= 0) {
// 处理超时错误(可选)
printf("JESD Reset Timeout!\n");
}
else{
printf("JESD Reset Done!\n");
}
}