From 0bfce37fae6f2913329d2ab862c7e159e39fcf9d Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sat, 18 Feb 2017 13:32:40 +0800 Subject: [PATCH] satman: do not use Si5324 automatic clock switching The Si5324 is easily confused by the broken clock generated during link initialization with BruteforceClockAligner. This commit prevents this problem. --- artiq/firmware/libboard/si5324.rs | 27 ++++++++++++++++++--------- artiq/firmware/satman/lib.rs | 18 +++++++++++++++--- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/artiq/firmware/libboard/si5324.rs b/artiq/firmware/libboard/si5324.rs index 4dad303a6..d5d789a73 100644 --- a/artiq/firmware/libboard/si5324.rs +++ b/artiq/firmware/libboard/si5324.rs @@ -130,7 +130,7 @@ fn locked() -> Result { Ok((read(130)? & 0x01) == 0) // LOL_INT=0 } -pub fn setup_hitless_clock_switching(settings: &FrequencySettings) -> Result<()> { +pub fn setup(settings: &FrequencySettings) -> Result<()> { let s = map_frequency_settings(settings)?; reset(true); @@ -145,12 +145,12 @@ pub fn setup_hitless_clock_switching(settings: &FrequencySettings) -> Result<()> return Err("Si5324 does not have expected product number"); } - write(0, read(0)? | 0x40)?; // FREE_RUN=1 - write(1, (read(1)? & 0xf0) | 0b0100)?; // CK_PRIOR2=1 CK_PRIOR1=0 - write(2, (read(2)? & 0x0f) | (4 << 4))?; // BWSEL=4 - write(3, read(3)? | 0x10)?; // SQ_ICAL=1 - write(4, (read(4)? & 0x3f) | (0b10 << 6))?; // AUTOSEL_REG=b10 - write(6, (read(6)? & 0xc0) | 0b001111)?; // SFOUT2_REG=b001 SFOUT1_REG=b111 + write(0, read(0)? | 0x40)?; // FREE_RUN=1 + write(2, (read(2)? & 0x0f) | (4 << 4))?; // BWSEL=4 + write(21, read(21)? & 0xfe); // CKSEL_PIN=0 + write(3, (read(3)? & 0x3f) | (0b01 << 6) | 0x10)?; // CKSEL_REG=b01 SQ_ICAL=1 + write(4, (read(4)? & 0x3f) | (0b00 << 6))?; // AUTOSEL_REG=b00 + write(6, (read(6)? & 0xc0) | 0b001111)?; // SFOUT2_REG=b001 SFOUT1_REG=b111 write(25, (s.n1_hs << 5 ) as u8)?; write(31, (s.nc1_ls >> 16) as u8)?; write(32, (s.nc1_ls >> 8 ) as u8)?; @@ -164,8 +164,8 @@ pub fn setup_hitless_clock_switching(settings: &FrequencySettings) -> Result<()> write(46, (s.n32 >> 16) as u8)?; write(47, (s.n32 >> 8) as u8)?; write(48, (s.n32) as u8)?; - write(137, read(137)? | 0x01)?; // FASTLOCK=1 - write(136, read(136)? | 0x40)?; // ICAL=1 + write(137, read(137)? | 0x01)?; // FASTLOCK=1 + write(136, read(136)? | 0x40)?; // ICAL=1 let t = clock::get_ms(); while !locked()? { @@ -176,3 +176,12 @@ pub fn setup_hitless_clock_switching(settings: &FrequencySettings) -> Result<()> Ok(()) } + +pub fn select_ext_input(external: bool) -> Result<()> { + if external { + write(3, (read(3)? & 0x3f) | (0b00 << 6))?; // CKSEL_REG=b00 + } else { + write(3, (read(3)? & 0x3f) | (0b01 << 6))?; // CKSEL_REG=b01 + } + Ok(()) +} diff --git a/artiq/firmware/satman/lib.rs b/artiq/firmware/satman/lib.rs index ddaa6f934..4a507d3a5 100644 --- a/artiq/firmware/satman/lib.rs +++ b/artiq/firmware/satman/lib.rs @@ -32,6 +32,12 @@ const SI5324_SETTINGS: board::si5324::FrequencySettings n32 : 7139 }; +fn drtio_link_is_up() -> bool { + unsafe { + board::csr::drtio::link_status_read() == 1 + } +} + fn startup() { board::clock::init(); info!("ARTIQ satellite manager starting..."); @@ -41,10 +47,16 @@ fn startup() { #[cfg(has_ad9516)] board::ad9516::init().expect("cannot initialize ad9516"); board::i2c::init(); - board::si5324::setup_hitless_clock_switching(&SI5324_SETTINGS) - .expect("cannot initialize si5324"); + board::si5324::setup(&SI5324_SETTINGS).expect("cannot initialize si5324"); - loop {} + loop { + while !drtio_link_is_up() {} + info!("link is up, switching to recovered clock"); + board::si5324::select_ext_input(true).expect("failed to switch clocks"); + while drtio_link_is_up() {} + info!("link is down, switching to local crystal clock"); + board::si5324::select_ext_input(false).expect("failed to switch clocks"); + } } #[no_mangle]