forked from M-Labs/artiq
firmware: implement si5324 skew calibration
This commit is contained in:
parent
f7aba6b570
commit
74d1df3ff0
|
@ -278,7 +278,78 @@ pub fn select_recovered_clock(rc: bool) -> Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(has_si_phaser)]
|
#[cfg(has_si_phaser)]
|
||||||
pub fn calibrate_skew() -> Result<()> {
|
fn phase_shift(direction: u8) {
|
||||||
// TODO: implement
|
unsafe {
|
||||||
|
csr::si_phaser::phase_shift_write(direction);
|
||||||
|
while csr::si_phaser::phase_shift_done_read() == 0 {}
|
||||||
|
}
|
||||||
|
// wait for the Si5324 loop to stabilize
|
||||||
|
clock::spin_us(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(has_si_phaser)]
|
||||||
|
fn get_phaser_sample() -> bool {
|
||||||
|
let mut sample = true;
|
||||||
|
for _ in 0..32 {
|
||||||
|
if unsafe { csr::si_phaser::sample_result_read() } == 0 {
|
||||||
|
sample = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sample
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(has_si_phaser)]
|
||||||
|
const PS_MARGIN: u32 = 28;
|
||||||
|
|
||||||
|
#[cfg(has_si_phaser)]
|
||||||
|
fn get_stable_phaser_sample() -> (bool, u32) {
|
||||||
|
let mut nshifts: u32 = 0;
|
||||||
|
loop {
|
||||||
|
let s1 = get_phaser_sample();
|
||||||
|
for _ in 0..PS_MARGIN {
|
||||||
|
phase_shift(1);
|
||||||
|
}
|
||||||
|
let s2 = get_phaser_sample();
|
||||||
|
for _ in 0..PS_MARGIN {
|
||||||
|
phase_shift(1);
|
||||||
|
}
|
||||||
|
let s3 = get_phaser_sample();
|
||||||
|
nshifts += 2*PS_MARGIN;
|
||||||
|
if s1 == s2 && s2 == s3 {
|
||||||
|
for _ in 0..PS_MARGIN {
|
||||||
|
phase_shift(0);
|
||||||
|
}
|
||||||
|
nshifts -= PS_MARGIN;
|
||||||
|
return (s2, nshifts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(has_si_phaser)]
|
||||||
|
pub fn calibrate_skew(skew: u16) -> Result<()> {
|
||||||
|
// Get into a 0 region
|
||||||
|
let (s1, mut nshifts) = get_stable_phaser_sample();
|
||||||
|
if s1 {
|
||||||
|
while get_phaser_sample() {
|
||||||
|
phase_shift(1);
|
||||||
|
nshifts += 1;
|
||||||
|
}
|
||||||
|
for _ in 0..PS_MARGIN {
|
||||||
|
phase_shift(1);
|
||||||
|
}
|
||||||
|
nshifts += PS_MARGIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get to the 0->1 transition
|
||||||
|
while !get_phaser_sample() {
|
||||||
|
phase_shift(1);
|
||||||
|
nshifts += 1;
|
||||||
|
}
|
||||||
|
info!("nshifts to 0->1 siphaser transition: {} ({}deg)", nshifts, nshifts*360/(56*8));
|
||||||
|
|
||||||
|
// Apply specified skew referenced to that transition
|
||||||
|
for _ in 0..skew {
|
||||||
|
phase_shift(1);
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,7 +236,7 @@ fn startup() {
|
||||||
}
|
}
|
||||||
info!("link is up, switching to recovered clock");
|
info!("link is up, switching to recovered clock");
|
||||||
si5324::select_recovered_clock(true).expect("failed to switch clocks");
|
si5324::select_recovered_clock(true).expect("failed to switch clocks");
|
||||||
si5324::calibrate_skew().expect("failed to calibrate skew");
|
si5324::calibrate_skew(32).expect("failed to calibrate skew");
|
||||||
drtio_reset(false);
|
drtio_reset(false);
|
||||||
drtio_reset_phy(false);
|
drtio_reset_phy(false);
|
||||||
while drtio_link_rx_up() {
|
while drtio_link_rx_up() {
|
||||||
|
|
Loading…
Reference in New Issue