artiq/artiq/firmware/satman/jdac_common.rs

75 lines
2.3 KiB
Rust

pub const INIT: u8 = 0x00;
pub const PRINT_STATUS: u8 = 0x01;
pub const PRBS: u8 = 0x02;
pub const STPL: u8 = 0x03;
pub const SYSREF_DELAY_DAC: u8 = 0x10;
pub const SYSREF_SLIP: u8 = 0x11;
pub const SYNC: u8 = 0x12;
pub const DDMTD_SYSREF_RAW: u8 = 0x20;
pub const DDMTD_SYSREF: u8 = 0x21;
fn average_2phases(a: i32, b: i32, modulo: i32) -> i32 {
let diff = ((a - b + modulo/2 + modulo) % modulo) - modulo/2;
return (modulo + b + diff/2) % modulo;
}
pub fn average_phases(phases: &[i32], modulo: i32) -> i32 {
if phases.len() == 1 {
panic!("input array length must be a power of 2");
} else if phases.len() == 2 {
average_2phases(phases[0], phases[1], modulo)
} else {
let cut = phases.len()/2;
average_2phases(
average_phases(&phases[..cut], modulo),
average_phases(&phases[cut..], modulo),
modulo)
}
}
pub const RAW_DDMTD_N_SHIFT: i32 = 6;
pub const RAW_DDMTD_N: i32 = 1 << RAW_DDMTD_N_SHIFT;
pub const DDMTD_DITHER_BITS: i32 = 1;
pub const DDMTD_N_SHIFT: i32 = RAW_DDMTD_N_SHIFT + DDMTD_DITHER_BITS;
pub const DDMTD_N: i32 = 1 << DDMTD_N_SHIFT;
#[cfg(has_ad9154)]
use board_misoc::{clock, csr};
#[cfg(has_ad9154)]
pub fn init_ddmtd() -> Result<(), &'static str> {
unsafe {
csr::sysref_ddmtd::reset_write(1);
clock::spin_us(1);
csr::sysref_ddmtd::reset_write(0);
clock::spin_us(100);
if csr::sysref_ddmtd::locked_read() != 0 {
Ok(())
} else {
Err("DDMTD helper PLL failed to lock")
}
}
}
#[cfg(has_ad9154)]
pub fn measure_ddmdt_phase_raw() -> i32 {
unsafe { csr::sysref_ddmtd::dt_read() as i32 }
}
#[cfg(has_ad9154)]
pub fn measure_ddmdt_phase() -> i32 {
const AVG_PRECISION_SHIFT: i32 = 6;
const AVG_PRECISION: i32 = 1 << AVG_PRECISION_SHIFT;
const AVG_MOD: i32 = 1 << (RAW_DDMTD_N_SHIFT + AVG_PRECISION_SHIFT + DDMTD_DITHER_BITS);
let mut measurements = [0; AVG_PRECISION as usize];
for i in 0..AVG_PRECISION {
measurements[i as usize] = measure_ddmdt_phase_raw() << (AVG_PRECISION_SHIFT + DDMTD_DITHER_BITS);
clock::spin_us(10);
}
average_phases(&measurements, AVG_MOD) >> AVG_PRECISION_SHIFT
}