artiq-zynq/src/satman/jdcg.rs

139 lines
4.3 KiB
Rust

pub mod jesd {
use libboard_artiqzynq::pl::csr;
use libboard_zynq::timer::GlobalTimer;
pub fn reset(reset: bool) {
unsafe {
csr::jesd_crg::jreset_write(if reset {1} else {0});
}
}
pub fn enable(dacno: u8, en: bool) {
unsafe {
(csr::JDCG[dacno as usize].jesd_control_enable_write)(if en {1} else {0})
}
}
pub fn phy_done(dacno: u8) -> bool {
unsafe {
(csr::JDCG[dacno as usize].jesd_control_phy_done_read)() != 0
}
}
pub fn ready(dacno: u8) -> bool {
unsafe {
(csr::JDCG[dacno as usize].jesd_control_ready_read)() != 0
}
}
pub fn prbs(dacno: u8, en: bool, timer: GlobalTimer) {
unsafe {
(csr::JDCG[dacno as usize].jesd_control_prbs_config_write)(if en {0b01} else {0b00})
}
timer.delay_us(5000);
}
pub fn stpl(dacno: u8, en: bool, timer: GlobalTimer) {
unsafe {
(csr::JDCG[dacno as usize].jesd_control_stpl_enable_write)(if en {1} else {0})
}
timer.delay_us(5000);
}
pub fn jsync(dacno: u8) -> bool {
unsafe {
(csr::JDCG[dacno as usize].jesd_control_jsync_read)() != 0
}
}
}
pub mod jdac {
use libboard_artiqzynq::{pl::csr, drtioaux};
use libboard_zynq::timer::GlobalTimer;
use super::jesd;
use super::super::jdac_common;
pub fn basic_request(dacno: u8, reqno: u8, param: u8) -> Result<u8, &'static str> {
if let Err(e) = drtioaux::send(1, &drtioaux::Packet::JdacBasicRequest {
destination: 0,
dacno: dacno,
reqno: reqno,
param: param
}) {
error!("aux packet error ({})", e);
return Err("aux packet error while sending for JESD DAC basic request");
}
match drtioaux::recv_timeout(1, Some(1000)) {
Ok(drtioaux::Packet::JdacBasicReply { succeeded, retval }) => {
if succeeded {
Ok(retval)
} else {
error!("JESD DAC basic request failed (dacno={}, reqno={})", dacno, reqno);
Err("remote error status to JESD DAC basic request")
}
},
Ok(packet) => {
error!("received unexpected aux packet: {:?}", packet);
Err("unexpected aux packet in reply to JESD DAC basic request")
},
Err(e) => {
error!("aux packet error ({})", e);
Err("aux packet error while waiting for JESD DAC basic reply")
}
}
}
pub fn init(timer: GlobalTimer) -> Result<(), &'static str> {
for dacno in 0..csr::JDCG.len() {
let dacno = dacno as u8;
info!("DAC-{} initializing...", dacno);
jesd::enable(dacno, true);
timer.delay_us(10_000);
if !jesd::phy_done(dacno) {
error!("JESD core PHY not done");
return Err("JESD core PHY not done");
}
basic_request(dacno, jdac_common::INIT, 0)?;
// JESD ready depends on JSYNC being valid, so DAC init needs to happen first
if !jesd::ready(dacno) {
error!("JESD core reported not ready, sending DAC status print request");
basic_request(dacno, jdac_common::PRINT_STATUS, 0)?;
return Err("JESD core reported not ready");
}
jesd::prbs(dacno, true);
basic_request(dacno, jdac_common::PRBS, 0)?;
jesd::prbs(dacno, false);
basic_request(dacno, jdac_common::INIT, 0)?;
timer.delay_us(5000);
if !jesd::jsync(dacno) {
error!("JESD core reported bad SYNC");
return Err("JESD core reported bad SYNC");
}
info!(" ...done initializing");
}
Ok(())
}
pub fn stpl(timer: GlobalTimer) -> Result<(), &'static str> {
for dacno in 0..csr::JDCG.len() {
let dacno = dacno as u8;
info!("Running STPL test on DAC-{}...", dacno);
jesd::stpl(dacno, true, timer);
basic_request(dacno, jdac_common::STPL, 0)?;
jesd::stpl(dacno, false, timer);
info!(" ...done STPL test");
}
Ok(())
}
}