1
0
Fork 0

cxp downconn fw: change to 40bits

This commit is contained in:
morgan 2024-08-14 16:48:51 +08:00
parent 49d5cad5fd
commit aa128e1467
1 changed files with 123 additions and 67 deletions

View File

@ -1,6 +1,6 @@
use embedded_hal::prelude::_embedded_hal_blocking_delay_DelayUs; use embedded_hal::prelude::_embedded_hal_blocking_delay_DelayUs;
use libboard_zynq::{println, timer::GlobalTimer}; use libboard_zynq::{println, timer::GlobalTimer};
use log::{error, info}; use log::info;
// use log::info; // use log::info;
use crate::pl::csr; use crate::pl::csr;
@ -68,7 +68,7 @@ fn loopback_testing(timer: &mut GlobalTimer, data: u8, control_bit: u8) {
info!("waiting for rx to align..."); info!("waiting for rx to align...");
// timer.delay_us(50_000); // timer.delay_us(50_000);
// while csr::cxp::downconn_rx_ready_read() != 1 {} // while csr::cxp::downconn_rx_ready_read() != 1 {}
info!("rx ready!"); // info!("rx ready!");
// println!("0xA8 = {:#06x}", read(0x62)); // println!("0xA8 = {:#06x}", read(0x62));
// write(0x62, 0x001A); // write(0x62, 0x001A);
@ -76,27 +76,51 @@ fn loopback_testing(timer: &mut GlobalTimer, data: u8, control_bit: u8) {
// for _ in 0..20 { // for _ in 0..20 {
loop { loop {
// NOTE: raw data
let data0 = csr::cxp::downconn_rxdata_0_read(); let data0 = csr::cxp::downconn_rxdata_0_read();
// let data1 = csr::cxp::downconn_rxdata_1_read(); let data1 = csr::cxp::downconn_rxdata_1_read();
let rxready = csr::cxp::downconn_rx_ready_read(); // let rxready = csr::cxp::downconn_rx_ready_read();
// timer.delay_us(100); // timer.delay_us(100);
// timer.delay_us(1_000_000); // if data0 == 0b0101111100 || data0 == 0b1010000011 {
if data0 == 0b0101111100 || data0 == 0b1010000011 { // println!(
println!( // "data[0] = {:#012b} comma = {} | rx ready = {}",
"data[0] = {:#012b} comma = {} | rx ready = {}", // data0,
data0, // data0 == 0b0101111100 || data0 == 0b1010000011,
data0 == 0b0101111100 || data0 == 0b1010000011, // rxready,
rxready, // );
); // timer.delay_us(1_000_000);
timer.delay_us(1_000_000); // } else if data0 == 0b1001111100 || data0 == 0b0110000011 {
} // println!(
// "data[0] = {:#012b} K28.1 | rx ready = {}",
// data0,
// rxready,
// );
// timer.delay_us(1_000_000);
// } else {
// println!(
// "data[0] = {:#012b} | rx ready = {}",
// data0,
// rxready,
// );
// timer.delay_us(1_000_000);
// }
println!("0b{:010b}{:010b}", data0, data1);
timer.delay_us(1_000_000);
// NOTE:decode data
// let data0_decoded = csr::cxp::downconn_decoded_data_0_read();
// let data0_k = csr::cxp::downconn_decoded_k_0_read();
// let data1_decoded = csr::cxp::downconn_decoded_data_1_read();
// let data1_k = csr::cxp::downconn_decoded_k_1_read();
// println!( // println!(
// "decoded_data[0] = {:#04x} decoded_k[0] = {:#b} decoded_data[1] = {:#04x} decoded_k[1] = {:#b}", // "decoded_data[0] = {:#04x} decoded_k[0] = {:#b} decoded_data[1] = {:#04x} decoded_k[1] = {:#b}",
// csr::cxp::downconn_decoded_data_0_read(), // data0_decoded,
// csr::cxp::downconn_decoded_k_0_read(), // data0_k,
// csr::cxp::downconn_decoded_data_1_read(), // data1_decoded,
// csr::cxp::downconn_decoded_k_1_read(), // data1_k,
// ); // );
// timer.delay_us(1_000_000);
} }
} }
} }
@ -148,9 +172,7 @@ pub mod CXP_GTX {
let settings = txusrclk::get_txusrclk_config(speed); let settings = txusrclk::get_txusrclk_config(speed);
txusrclk::setup(timer, settings); txusrclk::setup(timer, settings);
// TODO: set QPLL_FBDIV via DRP
change_qpll_settings(speed); change_qpll_settings(speed);
change_cdr_cfg(speed); change_cdr_cfg(speed);
unsafe { unsafe {
@ -169,27 +191,28 @@ pub mod CXP_GTX {
fn change_qpll_settings(speed: CXP_SPEED) { fn change_qpll_settings(speed: CXP_SPEED) {
match speed { match speed {
CXP_SPEED::CXP_12 => { CXP_SPEED::CXP_12 => {
error!("CXP 12.5Gbps is not supported on zc706"); panic!("CXP 12.5Gbps is not supported on zc706");
} }
_ => {} _ => {}
} }
// DEBUG: this switches between High and Low band VCO // this switches between High and Low band VCO
// NOT needed if VCO can do 12.5GHz // NOT needed if VCO can do 12.5GHz
let qpll_cfg_reg0 = match speed { let qpll_cfg_reg0 = match speed {
// DEBUG: for ZC706 QPLL VCO that cannot go up to 12.5GHz // NOTE: for ZC706 QPLL VCO that cannot go up to 12.5GHz
CXP_SPEED::CXP_1 | CXP_SPEED::CXP_2 | CXP_SPEED::CXP_5 | CXP_SPEED::CXP_10 => 0x0181, CXP_SPEED::CXP_1 | CXP_SPEED::CXP_2 | CXP_SPEED::CXP_5 | CXP_SPEED::CXP_10 => 0x0181,
CXP_SPEED::CXP_3 | CXP_SPEED::CXP_6 | CXP_SPEED::CXP_12 => 0x01C1, CXP_SPEED::CXP_3 | CXP_SPEED::CXP_6 | CXP_SPEED::CXP_12 => 0x01C1,
}; };
// Change QPLL_REFCLK_DIV
let qpll_div_reg0 = match speed { let qpll_div_reg0 = match speed {
// DEBUG: for ZC706 QPLL VCO that cannot go up to 12.5GHz // NOTE: for ZC706 QPLL VCO that cannot go up to 12.5GHz
CXP_SPEED::CXP_1 | CXP_SPEED::CXP_2 | CXP_SPEED::CXP_5 | CXP_SPEED::CXP_10 => 0x8068, CXP_SPEED::CXP_1 | CXP_SPEED::CXP_2 | CXP_SPEED::CXP_5 | CXP_SPEED::CXP_10 => 0x8068,
CXP_SPEED::CXP_3 | CXP_SPEED::CXP_6 | CXP_SPEED::CXP_12 => 0x0068, CXP_SPEED::CXP_3 | CXP_SPEED::CXP_6 | CXP_SPEED::CXP_12 => 0x0068,
}; };
// Change QPLL_FBDIV
let qpll_div_reg1 = match speed { let qpll_div_reg1 = match speed {
// DEBUG: for ZC706 QPLL VCO that cannot go up to 12.5GHz
CXP_SPEED::CXP_1 | CXP_SPEED::CXP_2 | CXP_SPEED::CXP_5 | CXP_SPEED::CXP_10 => 0x0120, CXP_SPEED::CXP_1 | CXP_SPEED::CXP_2 | CXP_SPEED::CXP_5 | CXP_SPEED::CXP_10 => 0x0120,
CXP_SPEED::CXP_3 | CXP_SPEED::CXP_6 | CXP_SPEED::CXP_12 => 0x0170, CXP_SPEED::CXP_3 | CXP_SPEED::CXP_6 | CXP_SPEED::CXP_12 => 0x0170,
}; };
@ -207,13 +230,13 @@ pub mod CXP_GTX {
println!("0x36 = {:#018b}", qpll_read(0x36)); println!("0x36 = {:#018b}", qpll_read(0x36));
let divider = match speed { let divider = match speed {
// DEBUG: for ZC706 QPLL VCO that cannot go up to 12.5GHz // NOTE: for ZC706 QPLL VCO that cannot go up to 12.5GHz
CXP_SPEED::CXP_1 => 0b100, // Divided by 8 CXP_SPEED::CXP_1 => 0b100, // Divided by 8
CXP_SPEED::CXP_2 => 0b011, // Divided by 4 CXP_SPEED::CXP_2 => 0b011, // Divided by 4
CXP_SPEED::CXP_5 | CXP_SPEED::CXP_3 => 0b010, // Divided by 2 CXP_SPEED::CXP_5 | CXP_SPEED::CXP_3 => 0b010, // Divided by 2
CXP_SPEED::CXP_10 | CXP_SPEED::CXP_6 => 0b001, // Divided by 1 CXP_SPEED::CXP_10 | CXP_SPEED::CXP_6 => 0b001, // Divided by 1
CXP_SPEED::CXP_12 => 0b000, CXP_SPEED::CXP_12 => 0b000,
// DEBUG: for ZC706 QPLL VCO that go up to 12.5GHz // NOTE: for ZC706 QPLL VCO that go up to 12.5GHz
// CXP_SPEED::CXP_1 => 0b100, // Divided by 8 // CXP_SPEED::CXP_1 => 0b100, // Divided by 8
// CXP_SPEED::CXP_2 | CXP_SPEED::CXP_3 => 0b011, // Divided by 4 // CXP_SPEED::CXP_2 | CXP_SPEED::CXP_3 => 0b011, // Divided by 4
// CXP_SPEED::CXP_5 | CXP_SPEED::CXP_6 => 0b010, // Divided by 2 // CXP_SPEED::CXP_5 | CXP_SPEED::CXP_6 => 0b010, // Divided by 2
@ -227,8 +250,40 @@ pub mod CXP_GTX {
} }
fn change_cdr_cfg(speed: CXP_SPEED) { fn change_cdr_cfg(speed: CXP_SPEED) {
// NOTE: for ZC706 QPLL VCO that cannot go up to 12.5GHz
let cdr_cfg = match speed { let cdr_cfg = match speed {
CXP_SPEED::CXP_1 | CXP_SPEED::CXP_2 | CXP_SPEED::CXP_3 | CXP_SPEED::CXP_5 | CXP_SPEED::CXP_6 => { // Divided by 8
CXP_SPEED::CXP_1 => {
RX_CDR_CFG {
cfg_reg0: 0x0020, //0x0A8
cfg_reg1: 0x1008, //0x0A9
cfg_reg2: 0x23FF, //0x0AA
cfg_reg3: 0x0000, //0x0AB
cfg_reg4: 0x0003, //0x0AC
}
}
// Divided by 4
CXP_SPEED::CXP_2 => {
RX_CDR_CFG {
cfg_reg0: 0x0020, //0x0A8
cfg_reg1: 0x1010, //0x0A9
cfg_reg2: 0x23FF, //0x0AA
cfg_reg3: 0x0000, //0x0AB
cfg_reg4: 0x0003, //0x0AC
}
}
// Divided by 2
CXP_SPEED::CXP_3 | CXP_SPEED::CXP_5 => {
RX_CDR_CFG {
cfg_reg0: 0x0020, //0x0A8
cfg_reg1: 0x1020, //0x0A9
cfg_reg2: 0x23FF, //0x0AA
cfg_reg3: 0x0000, //0x0AB
cfg_reg4: 0x0003, //0x0AC
}
}
// Divided by 1
CXP_SPEED::CXP_6 => {
RX_CDR_CFG { RX_CDR_CFG {
cfg_reg0: 0x0020, //0x0A8 cfg_reg0: 0x0020, //0x0A8
cfg_reg1: 0x1040, //0x0A9 cfg_reg1: 0x1040, //0x0A9
@ -237,6 +292,7 @@ pub mod CXP_GTX {
cfg_reg4: 0x0003, //0x0AC cfg_reg4: 0x0003, //0x0AC
} }
} }
// Divided by 1
CXP_SPEED::CXP_10 | CXP_SPEED::CXP_12 => { CXP_SPEED::CXP_10 | CXP_SPEED::CXP_12 => {
RX_CDR_CFG { RX_CDR_CFG {
cfg_reg0: 0x0020, //0x0A8 cfg_reg0: 0x0020, //0x0A8
@ -431,6 +487,23 @@ pub mod txusrclk {
pub fn get_txusrclk_config(speed: CXP_SPEED) -> PLLSetting { pub fn get_txusrclk_config(speed: CXP_SPEED) -> PLLSetting {
match speed { match speed {
CXP_SPEED::CXP_1 => { CXP_SPEED::CXP_1 => {
// CLKFBOUT_MULT = 8, DIVCLK_DIVIDE = 1 , CLKOUT0_DIVIDE = 32
// TXUSRCLK=62.5MHz
PLLSetting {
clkout0_reg1: 0x1410, //0x08
clkout0_reg2: 0x0000, //0x09
clkfbout_reg1: 0x1104, //0x14
clkfbout_reg2: 0x0000, //0x15
div_reg: 0x1041, //0x16
lock_reg1: 0x03e8, //0x18
lock_reg2: 0x5801, //0x19
lock_reg3: 0xdbe9, //0x1A
power_reg: 0x0000, //0x28
filt_reg1: 0x9808, //0x4E
filt_reg2: 0x9100, //0x4F
}
}
CXP_SPEED::CXP_2 => {
// CLKFBOUT_MULT = 8, DIVCLK_DIVIDE = 1 , CLKOUT0_DIVIDE = 16 // CLKFBOUT_MULT = 8, DIVCLK_DIVIDE = 1 , CLKOUT0_DIVIDE = 16
// TXUSRCLK=62.5MHz // TXUSRCLK=62.5MHz
PLLSetting { PLLSetting {
@ -447,7 +520,24 @@ pub mod txusrclk {
filt_reg2: 0x9100, //0x4F filt_reg2: 0x9100, //0x4F
} }
} }
CXP_SPEED::CXP_2 => { CXP_SPEED::CXP_3 => {
// CLKFBOUT_MULT = 10, DIVCLK_DIVIDE = 1 , CLKOUT0_DIVIDE = 16
// TXUSRCLK=78.125MHz
PLLSetting {
clkout0_reg1: 0x1208, //0x08
clkout0_reg2: 0x0000, //0x09
clkfbout_reg1: 0x1145, //0x14
clkfbout_reg2: 0x0000, //0x15
div_reg: 0x1041, //0x16
lock_reg1: 0x03e8, //0x18
lock_reg2: 0x7001, //0x19
lock_reg3: 0xf3e9, //0x1A
power_reg: 0x0000, //0x28
filt_reg1: 0x9908, //0x4E
filt_reg2: 0x1900, //0x4F
}
}
CXP_SPEED::CXP_5 => {
// CLKFBOUT_MULT = 8, DIVCLK_DIVIDE = 1 , CLKOUT0_DIVIDE = 8 // CLKFBOUT_MULT = 8, DIVCLK_DIVIDE = 1 , CLKOUT0_DIVIDE = 8
// TXUSRCLK=125MHz // TXUSRCLK=125MHz
PLLSetting { PLLSetting {
@ -464,9 +554,9 @@ pub mod txusrclk {
filt_reg2: 0x9100, //0x4F filt_reg2: 0x9100, //0x4F
} }
} }
CXP_SPEED::CXP_3 => { CXP_SPEED::CXP_6 => {
// CLKFBOUT_MULT = 10, DIVCLK_DIVIDE = 1 , CLKOUT0_DIVIDE = 8 // CLKFBOUT_MULT = 10, DIVCLK_DIVIDE = 1 , CLKOUT0_DIVIDE = 8
// TXUSRCLK=125MHz // TXUSRCLK=156.25MHz
PLLSetting { PLLSetting {
clkout0_reg1: 0x1104, //0x08 clkout0_reg1: 0x1104, //0x08
clkout0_reg2: 0x0000, //0x09 clkout0_reg2: 0x0000, //0x09
@ -481,7 +571,7 @@ pub mod txusrclk {
filt_reg2: 0x1900, //0x4F filt_reg2: 0x1900, //0x4F
} }
} }
CXP_SPEED::CXP_5 => { CXP_SPEED::CXP_10 => {
// CLKFBOUT_MULT = 8, DIVCLK_DIVIDE = 1 , CLKOUT0_DIVIDE = 4 // CLKFBOUT_MULT = 8, DIVCLK_DIVIDE = 1 , CLKOUT0_DIVIDE = 4
// TXUSRCLK=250MHz // TXUSRCLK=250MHz
PLLSetting { PLLSetting {
@ -498,7 +588,7 @@ pub mod txusrclk {
filt_reg2: 0x9100, //0x4F filt_reg2: 0x9100, //0x4F
} }
} }
CXP_SPEED::CXP_6 => { CXP_SPEED::CXP_12 => {
// CLKFBOUT_MULT = 10, DIVCLK_DIVIDE = 1 , CLKOUT0_DIVIDE = 4 // CLKFBOUT_MULT = 10, DIVCLK_DIVIDE = 1 , CLKOUT0_DIVIDE = 4
// TXUSRCLK=312.5MHz // TXUSRCLK=312.5MHz
PLLSetting { PLLSetting {
@ -515,40 +605,6 @@ pub mod txusrclk {
filt_reg2: 0x1900, //0x4F filt_reg2: 0x1900, //0x4F
} }
} }
CXP_SPEED::CXP_10 => {
// CLKFBOUT_MULT = 8, DIVCLK_DIVIDE = 1 , CLKOUT0_DIVIDE = 2
// TXUSRCLK=500MHz
PLLSetting {
clkout0_reg1: 0x1041, //0x08
clkout0_reg2: 0x0000, //0x09
clkfbout_reg1: 0x1104, //0x14
clkfbout_reg2: 0x0000, //0x15
div_reg: 0x1041, //0x16
lock_reg1: 0x03e8, //0x18
lock_reg2: 0x5801, //0x19
lock_reg3: 0xdbe9, //0x1A
power_reg: 0x0000, //0x28
filt_reg1: 0x9808, //0x4E
filt_reg2: 0x9100, //0x4F
}
}
CXP_SPEED::CXP_12 => {
// CLKFBOUT_MULT = 10, DIVCLK_DIVIDE = 1 , CLKOUT0_DIVIDE = 2
// TXUSRCLK=625MHz
PLLSetting {
clkout0_reg1: 0x1041, //0x08
clkout0_reg2: 0x0000, //0x09
clkfbout_reg1: 0x1145, //0x14
clkfbout_reg2: 0x0000, //0x15
div_reg: 0x1041, //0x16
lock_reg1: 0x03e8, //0x18
lock_reg2: 0x7001, //0x19
lock_reg3: 0xf3e9, //0x1A
power_reg: 0x0000, //0x28
filt_reg1: 0x9908, //0x4E
filt_reg2: 0x1900, //0x4F
}
}
} }
} }
} }