forked from M-Labs/artiq
firmware: use aux ping to determine when DRTIO satellite is ready
This commit is contained in:
parent
a8ea557406
commit
257527629a
|
@ -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",
|
||||
|
|
|
@ -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 }
|
||||
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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");
|
||||
|
||||
io.sleep(10000).unwrap();
|
||||
info!("wait for remote side done");
|
||||
info!("link RX is up, pinging");
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue