diff --git a/src/libboard_artiq/src/cxp_downconn.rs b/src/libboard_artiq/src/cxp_downconn.rs index 64b842e..c0e7963 100644 --- a/src/libboard_artiq/src/cxp_downconn.rs +++ b/src/libboard_artiq/src/cxp_downconn.rs @@ -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) {} + } } }