1
0
Fork 0

cxp downconn fw: put drp into mod & add rxcdr_cfg

This commit is contained in:
morgan 2024-08-12 17:44:26 +08:00
parent 5dfef7e457
commit 5ddd2cd730
1 changed files with 88 additions and 48 deletions

View File

@ -69,11 +69,10 @@ fn loopback_testing(timer: &mut GlobalTimer, data: u8, control_bit: u8) {
// while csr::cxp::downconn_rx_ready_read() != 1 {}
info!("rx ready!");
println!("0xA8 = {:#06x}", read(0x62));
write(0x62, 0x001A);
println!("0xA8 = {:#06x}", read(0x62));
// println!("0xA8 = {:#06x}", read(0x62));
// write(0x62, 0x001A);
// println!("0xA8 = {:#06x}", read(0x62));
println!("shifted = {}", csr::cxp::downconn_shifted_read());
// for _ in 0..20 {
loop {
let data0 = csr::cxp::downconn_rxdata_0_read();
@ -126,64 +125,105 @@ pub fn setup(timer: &mut GlobalTimer, speed: CXP_SPEED) {
println!("==============================================================================");
}
change_linerate(timer, speed);
CXP_GTX::change_linerate(timer, speed);
loopback_testing(timer, 0x00, 0);
}
pub fn change_linerate(timer: &mut GlobalTimer, speed: CXP_SPEED) {
info!("Changing datarate to {:?}", speed);
// DEBUG: DRP pll for TXUSRCLK = freq(linerate)/20
let settings = txusrclk::get_txusrclk_config(speed);
txusrclk::setup(timer, settings);
pub mod CXP_GTX {
use super::*;
// TODO: set QPLL_FBDIV via DRP
change_qpll_settings(speed);
unsafe {
csr::cxp::downconn_qpll_reset_write(1);
info!("waiting for QPLL/CPLL to lock...");
while csr::cxp::downconn_qpll_locked_read() != 1 {}
info!("QPLL locked");
struct RX_CDR_CFG {
pub cfg_reg0: u16, //0x0A8
pub cfg_reg1: u16, //0x0A9
pub cfg_reg2: u16, //0x0AA
pub cfg_reg3: u16, //0x0AB
pub cfg_reg4: u16, //0x0AC
}
unsafe {
csr::cxp::downconn_tx_restart_write(1);
csr::cxp::downconn_rx_restart_write(1);
pub fn change_linerate(timer: &mut GlobalTimer, speed: CXP_SPEED) {
info!("Changing datarate to {:?}", speed);
// DEBUG: DRP pll for TXUSRCLK = freq(linerate)/20
let settings = txusrclk::get_txusrclk_config(speed);
txusrclk::setup(timer, settings);
// TODO: set QPLL_FBDIV via DRP
change_qpll_settings(speed);
change_cdr_cfg(speed);
unsafe {
csr::cxp::downconn_qpll_reset_write(1);
info!("waiting for QPLL/CPLL to lock...");
while csr::cxp::downconn_qpll_locked_read() != 1 {}
info!("QPLL locked");
}
unsafe {
csr::cxp::downconn_tx_restart_write(1);
csr::cxp::downconn_rx_restart_write(1);
}
}
}
fn change_qpll_settings(speed: CXP_SPEED) {
let divider = match speed {
CXP_SPEED::CXP_1 => 0b100, // Divided by 8
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_10 | CXP_SPEED::CXP_12 => 0b010, // Divided by 1
};
fn change_qpll_settings(speed: CXP_SPEED) {
let divider = match speed {
CXP_SPEED::CXP_1 => 0b100, // Divided by 8
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_10 | CXP_SPEED::CXP_12 => 0b001, // Divided by 1
};
unsafe {
csr::cxp::downconn_rx_div_write(divider);
csr::cxp::downconn_tx_div_write(divider);
unsafe {
csr::cxp::downconn_rx_div_write(divider);
csr::cxp::downconn_tx_div_write(divider);
}
}
}
fn read(address: u16) -> u16 {
// DEBUG: DRPCLK need to be on for a few cycle before accessing other DRP ports
unsafe {
csr::cxp::downconn_gtx_daddr_write(address);
csr::cxp::downconn_gtx_dread_write(1);
while (csr::cxp::downconn_gtx_dready_read() != 1) {}
csr::cxp::downconn_gtx_dout_read()
fn change_cdr_cfg(speed: CXP_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 => {
RX_CDR_CFG {
cfg_reg0: 0x0020, //0x0A8
cfg_reg1: 0x1040, //0x0A9
cfg_reg2: 0x23FF, //0x0AA
cfg_reg3: 0x0000, //0x0AB
cfg_reg4: 0x0003, //0x0AC
}
}
CXP_SPEED::CXP_10 | CXP_SPEED::CXP_12 => {
RX_CDR_CFG {
cfg_reg0: 0x0020, //0x0A8
cfg_reg1: 0x1040, //0x0A9
cfg_reg2: 0x23FF, //0x0AA
cfg_reg3: 0x0000, //0x0AB
cfg_reg4: 0x000B, //0x0AC
}
}
};
println!("0x0AC = {}", read(0x0AC));
write(0x0AC, cdr_cfg.cfg_reg4);
println!("0x0AC = {}", read(0x0AC));
}
}
fn write(address: u16, value: u16) {
// DEBUG: DRPCLK need to be on for a few cycle before accessing other DRP ports
unsafe {
csr::cxp::downconn_gtx_daddr_write(address);
csr::cxp::downconn_gtx_din_write(value);
csr::cxp::downconn_gtx_din_stb_write(1);
while (csr::cxp::downconn_gtx_dready_read() != 1) {}
fn read(address: u16) -> u16 {
// DEBUG: DRPCLK need to be on for a few cycle before accessing other DRP ports
unsafe {
csr::cxp::downconn_gtx_daddr_write(address);
csr::cxp::downconn_gtx_dread_write(1);
while (csr::cxp::downconn_gtx_dready_read() != 1) {}
csr::cxp::downconn_gtx_dout_read()
}
}
fn write(address: u16, value: u16) {
// DEBUG: DRPCLK need to be on for a few cycle before accessing other DRP ports
unsafe {
csr::cxp::downconn_gtx_daddr_write(address);
csr::cxp::downconn_gtx_din_write(value);
csr::cxp::downconn_gtx_din_stb_write(1);
while (csr::cxp::downconn_gtx_dready_read() != 1) {}
}
}
}