diff --git a/artiq/firmware/Cargo.lock b/artiq/firmware/Cargo.lock index 61bab6c85..220b2f394 100644 --- a/artiq/firmware/Cargo.lock +++ b/artiq/firmware/Cargo.lock @@ -52,6 +52,16 @@ name = "cslice" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "drtioaux" +version = "0.0.0" +dependencies = [ + "board 0.0.0", + "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "std_artiq 0.0.0", +] + [[package]] name = "fringe" version = "1.1.0" @@ -125,6 +135,7 @@ dependencies = [ "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "compiler_builtins 0.1.0 (git+https://github.com/rust-lang-nursery/compiler-builtins?rev=631b568)", "cslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "drtioaux 0.0.0", "fringe 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "logger_artiq 0.0.0", @@ -145,6 +156,7 @@ dependencies = [ "board 0.0.0", "build_artiq 0.0.0", "compiler_builtins 0.1.0 (git+https://github.com/rust-lang-nursery/compiler-builtins)", + "drtioaux 0.0.0", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "logger_artiq 0.0.0", "std_artiq 0.0.0", diff --git a/artiq/firmware/runtime/Cargo.toml b/artiq/firmware/runtime/Cargo.toml index 01aca8280..45666668b 100644 --- a/artiq/firmware/runtime/Cargo.toml +++ b/artiq/firmware/runtime/Cargo.toml @@ -19,6 +19,7 @@ logger_artiq = { path = "../liblogger_artiq" } cslice = { version = "0.3" } log = { version = "0.3", default-features = false, features = ["max_level_debug"] } board = { path = "../libboard", features = ["uart_console"] } +drtioaux = { path = "../libdrtioaux" } fringe = { version = "= 1.1.0", default-features = false, features = ["alloc"] } byteorder = { version = "1.0", default-features = false } diff --git a/artiq/firmware/runtime/lib.rs b/artiq/firmware/runtime/lib.rs index 4331db43d..b8d477615 100644 --- a/artiq/firmware/runtime/lib.rs +++ b/artiq/firmware/runtime/lib.rs @@ -14,6 +14,8 @@ extern crate fringe; extern crate smoltcp; #[macro_use] extern crate board; +#[cfg(has_drtio)] +extern crate drtioaux; use std::boxed::Box; use smoltcp::wire::{EthernetAddress, IpAddress}; diff --git a/artiq/firmware/runtime/rtio_mgt.rs b/artiq/firmware/runtime/rtio_mgt.rs index 44ae8a1ef..d83b15c6b 100644 --- a/artiq/firmware/runtime/rtio_mgt.rs +++ b/artiq/firmware/runtime/rtio_mgt.rs @@ -39,12 +39,27 @@ pub mod crg { #[cfg(has_drtio)] mod drtio { use super::*; + use drtioaux; pub fn startup(io: &Io) { io.spawn(4096, link_thread); io.spawn(4096, error_thread); } + static mut LINK_RUNNING: bool = false; + + fn link_set_running(running: bool) { + unsafe { + LINK_RUNNING = running + } + } + + fn link_is_running() -> bool { + unsafe { + LINK_RUNNING + } + } + fn link_is_up() -> bool { unsafe { csr::drtio::link_status_read() == 1 @@ -80,7 +95,7 @@ mod drtio { } pub fn init() { - if link_is_up() { + if link_is_running() { unsafe { csr::drtio::reset_write(1); while csr::drtio::o_wait_read() == 1 {} @@ -91,20 +106,40 @@ mod drtio { } } + fn ping_remote(io: &Io) -> u32 { + let mut count = 0; + loop { + if !link_is_up() { + return 0 + } + count += 1; + drtioaux::send_packet(&drtioaux::Packet::EchoRequest).unwrap(); + io.sleep(100).unwrap(); + let pr = drtioaux::recv_packet(); + match pr { + Ok(Some(drtioaux::Packet::EchoReply)) => return count, + _ => {} + } + } + } + pub fn link_thread(io: Io) { loop { io.until(link_is_up).unwrap(); - info!("link RX is up"); + info!("link RX is up, pinging"); - io.sleep(10000).unwrap(); - info!("wait for remote side done"); - - init(); // clear all FIFOs first - reset_phy(); - sync_tsc(); - info!("link initialization completed"); + let ping_count = ping_remote(&io); + if ping_count > 0 { + info!("remote replied after {} packets", ping_count); + link_set_running(true); + init(); // clear all FIFOs first + reset_phy(); + sync_tsc(); + info!("link initialization completed"); + } io.until(|| !link_is_up()).unwrap(); + link_set_running(false); info!("link is down"); } } diff --git a/artiq/firmware/satman/Cargo.toml b/artiq/firmware/satman/Cargo.toml index 5a4b6c938..92800d42c 100644 --- a/artiq/firmware/satman/Cargo.toml +++ b/artiq/firmware/satman/Cargo.toml @@ -17,6 +17,7 @@ alloc_artiq = { path = "../liballoc_artiq" } std_artiq = { path = "../libstd_artiq", features = ["alloc"] } logger_artiq = { path = "../liblogger_artiq" } board = { path = "../libboard", features = ["uart_console"] } +drtioaux = { path = "../libdrtioaux" } log = { version = "0.3", default-features = false } [dependencies.compiler_builtins] diff --git a/artiq/firmware/satman/lib.rs b/artiq/firmware/satman/lib.rs index 107b366aa..1051bfb67 100644 --- a/artiq/firmware/satman/lib.rs +++ b/artiq/firmware/satman/lib.rs @@ -9,6 +9,26 @@ extern crate std_artiq as std; extern crate log; extern crate logger_artiq; extern crate board; +extern crate drtioaux; + + +fn process_aux_packet(p: drtioaux::Packet) { + match p { + drtioaux::Packet::EchoRequest => drtioaux::send_packet(&drtioaux::Packet::EchoReply).unwrap(), + _ => warn!("received unexpected aux packet {:?}", p) + } +} + + +fn process_aux_packets() { + let pr = drtioaux::recv_packet(); + match pr { + Ok(None) => {}, + Ok(Some(p)) => process_aux_packet(p), + Err(e) => warn!("aux packet error ({})", e) + } +} + #[cfg(rtio_frequency = "62.5")] const SI5324_SETTINGS: board::si5324::FrequencySettings @@ -55,7 +75,9 @@ fn startup() { 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() {} + while drtio_link_is_up() { + process_aux_packets(); + } info!("link is down, switching to local crystal clock"); board::si5324::select_ext_input(false).expect("failed to switch clocks"); }