firmware: use aux ping to determine when DRTIO satellite is ready

This commit is contained in:
Sebastien Bourdeauducq 2017-02-22 15:26:32 +08:00
parent a8ea557406
commit 257527629a
6 changed files with 83 additions and 10 deletions

View File

@ -52,6 +52,16 @@ name = "cslice"
version = "0.3.0" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" 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]] [[package]]
name = "fringe" name = "fringe"
version = "1.1.0" version = "1.1.0"
@ -125,6 +135,7 @@ dependencies = [
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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)", "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)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"logger_artiq 0.0.0", "logger_artiq 0.0.0",
@ -145,6 +156,7 @@ dependencies = [
"board 0.0.0", "board 0.0.0",
"build_artiq 0.0.0", "build_artiq 0.0.0",
"compiler_builtins 0.1.0 (git+https://github.com/rust-lang-nursery/compiler-builtins)", "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)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"logger_artiq 0.0.0", "logger_artiq 0.0.0",
"std_artiq 0.0.0", "std_artiq 0.0.0",

View File

@ -19,6 +19,7 @@ logger_artiq = { path = "../liblogger_artiq" }
cslice = { version = "0.3" } cslice = { version = "0.3" }
log = { version = "0.3", default-features = false, features = ["max_level_debug"] } log = { version = "0.3", default-features = false, features = ["max_level_debug"] }
board = { path = "../libboard", features = ["uart_console"] } board = { path = "../libboard", features = ["uart_console"] }
drtioaux = { path = "../libdrtioaux" }
fringe = { version = "= 1.1.0", default-features = false, features = ["alloc"] } fringe = { version = "= 1.1.0", default-features = false, features = ["alloc"] }
byteorder = { version = "1.0", default-features = false } byteorder = { version = "1.0", default-features = false }

View File

@ -14,6 +14,8 @@ extern crate fringe;
extern crate smoltcp; extern crate smoltcp;
#[macro_use] #[macro_use]
extern crate board; extern crate board;
#[cfg(has_drtio)]
extern crate drtioaux;
use std::boxed::Box; use std::boxed::Box;
use smoltcp::wire::{EthernetAddress, IpAddress}; use smoltcp::wire::{EthernetAddress, IpAddress};

View File

@ -39,12 +39,27 @@ pub mod crg {
#[cfg(has_drtio)] #[cfg(has_drtio)]
mod drtio { mod drtio {
use super::*; use super::*;
use drtioaux;
pub fn startup(io: &Io) { pub fn startup(io: &Io) {
io.spawn(4096, link_thread); io.spawn(4096, link_thread);
io.spawn(4096, error_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 { fn link_is_up() -> bool {
unsafe { unsafe {
csr::drtio::link_status_read() == 1 csr::drtio::link_status_read() == 1
@ -80,7 +95,7 @@ mod drtio {
} }
pub fn init() { pub fn init() {
if link_is_up() { if link_is_running() {
unsafe { unsafe {
csr::drtio::reset_write(1); csr::drtio::reset_write(1);
while csr::drtio::o_wait_read() == 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) { pub fn link_thread(io: Io) {
loop { loop {
io.until(link_is_up).unwrap(); io.until(link_is_up).unwrap();
info!("link RX is up"); info!("link RX is up, pinging");
io.sleep(10000).unwrap(); let ping_count = ping_remote(&io);
info!("wait for remote side done"); if ping_count > 0 {
info!("remote replied after {} packets", ping_count);
init(); // clear all FIFOs first link_set_running(true);
reset_phy(); init(); // clear all FIFOs first
sync_tsc(); reset_phy();
info!("link initialization completed"); sync_tsc();
info!("link initialization completed");
}
io.until(|| !link_is_up()).unwrap(); io.until(|| !link_is_up()).unwrap();
link_set_running(false);
info!("link is down"); info!("link is down");
} }
} }

View File

@ -17,6 +17,7 @@ alloc_artiq = { path = "../liballoc_artiq" }
std_artiq = { path = "../libstd_artiq", features = ["alloc"] } std_artiq = { path = "../libstd_artiq", features = ["alloc"] }
logger_artiq = { path = "../liblogger_artiq" } logger_artiq = { path = "../liblogger_artiq" }
board = { path = "../libboard", features = ["uart_console"] } board = { path = "../libboard", features = ["uart_console"] }
drtioaux = { path = "../libdrtioaux" }
log = { version = "0.3", default-features = false } log = { version = "0.3", default-features = false }
[dependencies.compiler_builtins] [dependencies.compiler_builtins]

View File

@ -9,6 +9,26 @@ extern crate std_artiq as std;
extern crate log; extern crate log;
extern crate logger_artiq; extern crate logger_artiq;
extern crate board; 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")] #[cfg(rtio_frequency = "62.5")]
const SI5324_SETTINGS: board::si5324::FrequencySettings const SI5324_SETTINGS: board::si5324::FrequencySettings
@ -55,7 +75,9 @@ fn startup() {
while !drtio_link_is_up() {} while !drtio_link_is_up() {}
info!("link is up, switching to recovered clock"); info!("link is up, switching to recovered clock");
board::si5324::select_ext_input(true).expect("failed to switch clocks"); 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"); info!("link is down, switching to local crystal clock");
board::si5324::select_ext_input(false).expect("failed to switch clocks"); board::si5324::select_ext_input(false).expect("failed to switch clocks");
} }