diff --git a/artiq/firmware/runtime/rtio_mgt.rs b/artiq/firmware/runtime/rtio_mgt.rs index f2a606d86..a8685e1bd 100644 --- a/artiq/firmware/runtime/rtio_mgt.rs +++ b/artiq/firmware/runtime/rtio_mgt.rs @@ -114,23 +114,21 @@ pub mod drtio { } } - fn wait_tsc_ack(linkno: u8, io: &Io) -> bool { + fn wait_tsc_ack(linkno: u8, io: &Io) -> Result<(), &'static str> { loop { let mut count = 0; if !link_rx_up(linkno) { - return false; + return Err("link went down"); } count += 1; if count > 200 { - return false; + return Err("timeout"); } io.sleep(100).unwrap(); // TSCAck is the only aux packet that is sent spontaneously // by the satellite, in response to a TSC set on the RT link. - let pr = drtioaux::recv_link(linkno); - match pr { - Ok(Some(drtioaux::Packet::TSCAck)) => return true, - _ => {} + if let Ok(Some(drtioaux::Packet::TSCAck)) = drtioaux::recv_link(linkno) { + return Ok(()) } } } @@ -194,13 +192,13 @@ pub mod drtio { set_link_up(linkno, true); init_buffer_space(linkno); sync_tsc(linkno); - if !wait_tsc_ack(linkno, &io) { - info!("[LINK#{}] remote failed to ack TSC", linkno); + if wait_tsc_ack(linkno, &io).is_err() { + error!("[LINK#{}] remote failed to ack TSC", linkno); } else { info!("[LINK#{}] link initialization completed", linkno); } } else { - info!("[LINK#{}] ping failed", linkno); + error!("[LINK#{}] ping failed", linkno); } } } diff --git a/artiq/firmware/satman/main.rs b/artiq/firmware/satman/main.rs index 2bce73681..8ca8a6b6a 100644 --- a/artiq/firmware/satman/main.rs +++ b/artiq/firmware/satman/main.rs @@ -298,7 +298,7 @@ pub extern fn main() -> i32 { } } - info!("link is up, switching to recovered clock"); + info!("uplink is up, switching to recovered clock"); si5324::siphaser::select_recovered_clock(true).expect("failed to switch clocks"); si5324::siphaser::calibrate_skew(SIPHASER_PHASE).expect("failed to calibrate skew"); @@ -332,7 +332,7 @@ pub extern fn main() -> i32 { rep.service(); } if drtiosat_tsc_loaded() { - info!("TSC loaded"); + info!("TSC loaded from uplink"); #[cfg(has_ad9154)] { if let Err(e) = board_artiq::jesd204sync::sysref_auto_rtio_align() { @@ -343,7 +343,9 @@ pub extern fn main() -> i32 { } } for rep in repeaters.iter() { - rep.sync_tsc(); + if rep.sync_tsc().is_err() { + error!("remote failed to ack TSC"); + } } if let Err(e) = drtioaux::send_link(0, &drtioaux::Packet::TSCAck) { error!("aux packet error: {}", e); @@ -357,7 +359,7 @@ pub extern fn main() -> i32 { drtiosat_reset_phy(true); drtiosat_reset(true); drtiosat_tsc_loaded(); - info!("link is down, switching to local crystal clock"); + info!("uplink is down, switching to local crystal clock"); si5324::siphaser::select_recovered_clock(false).expect("failed to switch clocks"); } } diff --git a/artiq/firmware/satman/repeater.rs b/artiq/firmware/satman/repeater.rs index 686b3acbb..d677c362e 100644 --- a/artiq/firmware/satman/repeater.rs +++ b/artiq/firmware/satman/repeater.rs @@ -9,7 +9,7 @@ fn rep_link_rx_up(linkno: u8) -> bool { } } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, PartialEq)] enum RepeaterState { Down, SendPing { ping_count: u16 }, @@ -63,7 +63,7 @@ impl Repeater { if rep_link_rx_up(self.repno) { if let Ok(Some(drtioaux::Packet::EchoReply)) = drtioaux::recv_link(self.auxno) { info!("[REP#{}] remote replied after {} packets", self.repno, ping_count); - if !self.sync_tsc() { + if self.sync_tsc().is_err() { error!("[REP#{}] remote failed to ack TSC", self.repno); self.state = RepeaterState::Failed; return; @@ -100,7 +100,11 @@ impl Repeater { } } - pub fn sync_tsc(&self) -> bool { + pub fn sync_tsc(&self) -> Result<(), &'static str> { + if self.state != RepeaterState::Up { + return Ok(()); + } + let repno = self.repno as usize; unsafe { (csr::DRTIOREP[repno].set_time_write)(1); @@ -110,15 +114,15 @@ impl Repeater { let timeout = clock::get_ms() + 200; loop { if !rep_link_rx_up(self.repno) { - return false; + return Err("link went down"); } if clock::get_ms() > timeout { - return false; + return Err("timeout"); } // TSCAck is the only aux packet that is sent spontaneously // by the satellite, in response to a TSC set on the RT link. if let Ok(Some(drtioaux::Packet::TSCAck)) = drtioaux::recv_link(self.auxno) { - return true; + return Ok(()); } } } @@ -130,5 +134,5 @@ impl Repeater { pub fn service(&self) { } - pub fn sync_tsc(&self) { } + pub fn sync_tsc(&self) -> Result<(), &'static str> { Ok(()) } }