From 87ce24e8675b99acf922e8c6416a73b0d4074945 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Fri, 14 Jun 2019 15:26:30 +0800 Subject: [PATCH] runtime: refactor startup and RTIO clocking initialization --- artiq/firmware/runtime/main.rs | 136 ++++---------------- artiq/firmware/runtime/rtio_clocking.rs | 162 ++++++++++++++++++++++++ artiq/firmware/runtime/rtio_mgt.rs | 81 ------------ artiq/firmware/runtime/session.rs | 6 +- 4 files changed, 188 insertions(+), 197 deletions(-) create mode 100644 artiq/firmware/runtime/rtio_clocking.rs diff --git a/artiq/firmware/runtime/main.rs b/artiq/firmware/runtime/main.rs index 32dddc887..97b6b88e2 100644 --- a/artiq/firmware/runtime/main.rs +++ b/artiq/firmware/runtime/main.rs @@ -41,6 +41,7 @@ use proto_artiq::{mgmt_proto, moninj_proto, rpc_proto, session_proto, kernel_pro #[cfg(has_rtio_analyzer)] use proto_artiq::analyzer_proto; +mod rtio_clocking; mod rtio_mgt; mod urc; @@ -59,14 +60,15 @@ mod moninj; #[cfg(has_rtio_analyzer)] mod analyzer; -fn startup() { - irq::set_mask(0); - irq::set_ie(true); - clock::init(); - info!("ARTIQ runtime starting..."); - info!("software ident {}", csr::CONFIG_IDENTIFIER_STR); - info!("gateware ident {}", ident::read(&mut [0; 64])); +#[cfg(has_grabber)] +fn grabber_thread(io: sched::Io) { + loop { + board_artiq::grabber::tick(); + io.sleep(200).unwrap(); + } +} +fn setup_log_levels() { match config::read_str("log_level", |r| r.map(|s| s.parse())) { Ok(Ok(log_level_filter)) => { info!("log level set to {} by `log_level` config key", @@ -84,30 +86,14 @@ fn startup() { } _ => info!("UART log level set to INFO by default") } +} +fn sayma_hw_init() { #[cfg(has_slave_fpga_cfg)] board_artiq::slave_fpga::load().expect("cannot load RTM FPGA gateware"); #[cfg(has_serwb_phy_amc)] board_artiq::serwb::wait_init(); - #[cfg(has_uart)] { - let t = clock::get_ms(); - info!("press 'e' to erase startup and idle kernels..."); - while clock::get_ms() < t + 1000 { - if unsafe { csr::uart::rxtx_read() == b'e' } { - config::remove("startup_kernel").unwrap(); - config::remove("idle_kernel").unwrap(); - info!("startup and idle kernels erased"); - break - } - } - info!("continuing boot"); - } - - #[cfg(has_i2c)] - board_artiq::i2c::init(); - #[cfg(si5324_as_synthesizer)] - setup_si5324_as_synthesizer(); #[cfg(has_hmc830_7043)] /* must be the first SPI init because of HMC830 SPI mode selection */ board_artiq::hmc830_7043::init().expect("cannot initialize HMC830/7043"); @@ -124,98 +110,22 @@ fn startup() { } #[cfg(has_allaki_atts)] board_artiq::hmc542::program_all(8/*=4dB*/); - - #[cfg(has_ethmac)] - startup_ethernet(); - #[cfg(not(has_ethmac))] - { - info!("done"); - loop {} - } } -#[cfg(si5324_as_synthesizer)] -fn setup_si5324_as_synthesizer() -{ - // 125MHz output, from 100MHz CLKIN2 reference, 586 Hz loop bandwidth - #[cfg(all(rtio_frequency = "125.0", si5324_ext_ref, ext_ref_frequency = "100.0"))] - const SI5324_SETTINGS: board_artiq::si5324::FrequencySettings - = board_artiq::si5324::FrequencySettings { - n1_hs : 10, - nc1_ls : 4, - n2_hs : 10, - n2_ls : 260, - n31 : 65, - n32 : 52, - bwsel : 4, - crystal_ref: false - }; - // 125MHz output, from 125MHz CLKIN2 reference, 606 Hz loop bandwidth - #[cfg(all(rtio_frequency = "125.0", si5324_ext_ref, ext_ref_frequency = "125.0"))] - const SI5324_SETTINGS: board_artiq::si5324::FrequencySettings - = board_artiq::si5324::FrequencySettings { - n1_hs : 5, - nc1_ls : 8, - n2_hs : 7, - n2_ls : 360, - n31 : 63, - n32 : 63, - bwsel : 4, - crystal_ref: false - }; - // 125MHz output, from crystal, 7 Hz - #[cfg(all(rtio_frequency = "125.0", not(si5324_ext_ref)))] - const SI5324_SETTINGS: board_artiq::si5324::FrequencySettings - = board_artiq::si5324::FrequencySettings { - n1_hs : 10, - nc1_ls : 4, - n2_hs : 10, - n2_ls : 19972, - n31 : 4993, - n32 : 4565, - bwsel : 4, - crystal_ref: true - }; - // 150MHz output, from crystal - #[cfg(all(rtio_frequency = "150.0", not(si5324_ext_ref)))] - const SI5324_SETTINGS: board_artiq::si5324::FrequencySettings - = board_artiq::si5324::FrequencySettings { - n1_hs : 9, - nc1_ls : 4, - n2_hs : 10, - n2_ls : 33732, - n31 : 9370, - n32 : 7139, - bwsel : 3, - crystal_ref: true - }; - // 100MHz output, from crystal. Also used as reference for Sayma HMC830. - #[cfg(all(rtio_frequency = "100.0", not(si5324_ext_ref)))] - const SI5324_SETTINGS: board_artiq::si5324::FrequencySettings - = board_artiq::si5324::FrequencySettings { - n1_hs : 9, - nc1_ls : 6, - n2_hs : 10, - n2_ls : 33732, - n31 : 9370, - n32 : 7139, - bwsel : 3, - crystal_ref: true - }; - board_artiq::si5324::setup(&SI5324_SETTINGS, - board_artiq::si5324::Input::Ckin2).expect("cannot initialize Si5324"); -} +fn startup() { + irq::set_mask(0); + irq::set_ie(true); + clock::init(); + info!("ARTIQ runtime starting..."); + info!("software ident {}", csr::CONFIG_IDENTIFIER_STR); + info!("gateware ident {}", ident::read(&mut [0; 64])); -#[cfg(has_grabber)] -fn grabber_thread(io: sched::Io) { - loop { - board_artiq::grabber::tick(); - io.sleep(200).unwrap(); - } -} + setup_log_levels(); + #[cfg(has_i2c)] + board_artiq::i2c::init(); + sayma_hw_init(); + rtio_clocking::init(); -#[cfg(has_ethmac)] -fn startup_ethernet() { let hardware_addr; match config::read_str("mac", |r| r.map(|s| s.parse())) { Ok(Ok(addr)) => { diff --git a/artiq/firmware/runtime/rtio_clocking.rs b/artiq/firmware/runtime/rtio_clocking.rs new file mode 100644 index 000000000..5d9382dfc --- /dev/null +++ b/artiq/firmware/runtime/rtio_clocking.rs @@ -0,0 +1,162 @@ +use board_misoc::config; +#[cfg(si5324_as_synthesizer)] +use board_artiq::si5324; +#[cfg(has_drtio)] +use board_misoc::csr; + +#[derive(Debug)] +pub enum RtioClock { + Internal = 0, + External = 1 +} + +fn get_rtio_clock_cfg() -> RtioClock { + config::read("rtio_clock", |result| { + match result { + Ok(b"i") => { + info!("using internal RTIO clock"); + RtioClock::Internal + }, + Ok(b"e") => { + info!("using external RTIO clock"); + RtioClock::External + }, + _ => { + info!("using internal RTIO clock (by default)"); + RtioClock::Internal + }, + } + }) +} + +#[cfg(has_rtio_crg)] +pub mod crg { + #[cfg(has_rtio_clock_switch)] + use super::RtioClock; + use board_misoc::{clock, csr}; + + pub fn check() -> bool { + unsafe { csr::rtio_crg::pll_locked_read() != 0 } + } + + #[cfg(has_rtio_clock_switch)] + pub fn init(clk: RtioClock) -> bool { + unsafe { + csr::rtio_crg::pll_reset_write(1); + csr::rtio_crg::clock_sel_write(clk as u8); + csr::rtio_crg::pll_reset_write(0); + } + clock::spin_us(150); + return check() + } + + #[cfg(not(has_rtio_clock_switch))] + pub fn init() -> bool { + unsafe { + csr::rtio_crg::pll_reset_write(0); + } + clock::spin_us(150); + return check() + } +} + +#[cfg(not(has_rtio_crg))] +pub mod crg { + pub fn check() -> bool { true } +} + +#[cfg(si5324_as_synthesizer)] +fn setup_si5324_as_synthesizer() { + // 125MHz output, from 100MHz CLKIN2 reference, 586 Hz loop bandwidth + #[cfg(all(rtio_frequency = "125.0", si5324_ext_ref, ext_ref_frequency = "100.0"))] + const SI5324_SETTINGS: si5324::FrequencySettings + = si5324::FrequencySettings { + n1_hs : 10, + nc1_ls : 4, + n2_hs : 10, + n2_ls : 260, + n31 : 65, + n32 : 52, + bwsel : 4, + crystal_ref: false + }; + // 125MHz output, from 125MHz CLKIN2 reference, 606 Hz loop bandwidth + #[cfg(all(rtio_frequency = "125.0", si5324_ext_ref, ext_ref_frequency = "125.0"))] + const SI5324_SETTINGS: si5324::FrequencySettings + = si5324::FrequencySettings { + n1_hs : 5, + nc1_ls : 8, + n2_hs : 7, + n2_ls : 360, + n31 : 63, + n32 : 63, + bwsel : 4, + crystal_ref: false + }; + // 125MHz output, from crystal, 7 Hz + #[cfg(all(rtio_frequency = "125.0", not(si5324_ext_ref)))] + const SI5324_SETTINGS: si5324::FrequencySettings + = si5324::FrequencySettings { + n1_hs : 10, + nc1_ls : 4, + n2_hs : 10, + n2_ls : 19972, + n31 : 4993, + n32 : 4565, + bwsel : 4, + crystal_ref: true + }; + // 150MHz output, from crystal + #[cfg(all(rtio_frequency = "150.0", not(si5324_ext_ref)))] + const SI5324_SETTINGS: si5324::FrequencySettings + = si5324::FrequencySettings { + n1_hs : 9, + nc1_ls : 4, + n2_hs : 10, + n2_ls : 33732, + n31 : 9370, + n32 : 7139, + bwsel : 3, + crystal_ref: true + }; + // 100MHz output, from crystal. Also used as reference for Sayma HMC830. + #[cfg(all(rtio_frequency = "100.0", not(si5324_ext_ref)))] + const SI5324_SETTINGS: si5324::FrequencySettings + = si5324::FrequencySettings { + n1_hs : 9, + nc1_ls : 6, + n2_hs : 10, + n2_ls : 33732, + n31 : 9370, + n32 : 7139, + bwsel : 3, + crystal_ref: true + }; + si5324::setup(&SI5324_SETTINGS, si5324::Input::Ckin2).expect("cannot initialize Si5324"); +} + +pub fn init() { + #[cfg(si5324_as_synthesizer)] + setup_si5324_as_synthesizer(); + + #[cfg(has_drtio)] + unsafe { + csr::drtio_transceiver::stable_clkin_write(1); + } + + #[cfg(has_rtio_crg)] + { + #[cfg(has_rtio_clock_switch)] + { + if !crg::init(get_rtio_clock_cfg()) { + error!("RTIO clock failed"); + } + } + #[cfg(not(has_rtio_clock_switch))] + { + if !crg::init() { + error!("RTIO clock failed"); + } + } + } +} diff --git a/artiq/firmware/runtime/rtio_mgt.rs b/artiq/firmware/runtime/rtio_mgt.rs index 00f9cc3ef..10ac429c6 100644 --- a/artiq/firmware/runtime/rtio_mgt.rs +++ b/artiq/firmware/runtime/rtio_mgt.rs @@ -3,46 +3,10 @@ use urc::Urc; use board_misoc::csr; #[cfg(has_drtio)] use board_misoc::clock; -#[cfg(has_rtio_clock_switch)] -use board_misoc::config; use board_artiq::drtio_routing; use sched::Io; use sched::Mutex; -#[cfg(has_rtio_crg)] -pub mod crg { - use board_misoc::{clock, csr}; - - pub fn check() -> bool { - unsafe { csr::rtio_crg::pll_locked_read() != 0 } - } - - #[cfg(has_rtio_clock_switch)] - pub fn init(clk: u8) -> bool { - unsafe { - csr::rtio_crg::pll_reset_write(1); - csr::rtio_crg::clock_sel_write(clk); - csr::rtio_crg::pll_reset_write(0); - } - clock::spin_us(150); - return check() - } - - #[cfg(not(has_rtio_clock_switch))] - pub fn init() -> bool { - unsafe { - csr::rtio_crg::pll_reset_write(0); - } - clock::spin_us(150); - return check() - } -} - -#[cfg(not(has_rtio_crg))] -pub mod crg { - pub fn check() -> bool { true } -} - #[cfg(has_drtio)] pub mod drtio { use super::*; @@ -51,9 +15,6 @@ pub mod drtio { pub fn startup(io: &Io, aux_mutex: &Mutex, routing_table: &Urc>, up_destinations: &Urc>) { - unsafe { - csr::drtio_transceiver::stable_clkin_write(1); - } let aux_mutex = aux_mutex.clone(); let routing_table = routing_table.clone(); let up_destinations = up_destinations.clone(); @@ -380,52 +341,10 @@ fn async_error_thread(io: Io) { pub fn startup(io: &Io, aux_mutex: &Mutex, routing_table: &Urc>, up_destinations: &Urc>) { - // The RTIO CRG may depend on the DRTIO transceiver clock. - // Initialize DRTIO first to bring up transceiver clocking. drtio::startup(io, aux_mutex, routing_table, up_destinations); - - #[cfg(has_rtio_crg)] - { - #[cfg(has_rtio_clock_switch)] - { - #[derive(Debug)] - enum RtioClock { - Internal = 0, - External = 1 - }; - - let clk = config::read("rtio_clock", |result| { - match result { - Ok(b"i") => { - info!("using internal RTIO clock"); - RtioClock::Internal - }, - Ok(b"e") => { - info!("using external RTIO clock"); - RtioClock::External - }, - _ => { - info!("using internal RTIO clock (by default)"); - RtioClock::Internal - }, - } - }); - - if !crg::init(clk as u8) { - error!("RTIO clock failed"); - } - } - #[cfg(not(has_rtio_clock_switch))] - { - if !crg::init() { - error!("RTIO clock failed"); - } - } - } unsafe { csr::rtio_core::reset_phy_write(1); } - io.spawn(4096, async_error_thread); } diff --git a/artiq/firmware/runtime/session.rs b/artiq/firmware/runtime/session.rs index 23760e038..f5c76cf35 100644 --- a/artiq/firmware/runtime/session.rs +++ b/artiq/firmware/runtime/session.rs @@ -7,7 +7,7 @@ use board_misoc::{ident, cache, config}; use {mailbox, rpc_queue, kernel}; use urc::Urc; use sched::{ThreadHandle, Io, Mutex, TcpListener, TcpStream, Error as SchedError}; -use rtio_mgt; +use rtio_clocking; use rtio_dma::Manager as DmaManager; use cache::Cache; use kern_hwreq; @@ -527,7 +527,7 @@ fn host_kernel_worker(io: &Io, aux_mutex: &Mutex, return Err(Error::WatchdogExpired(idx)) } - if !rtio_mgt::crg::check() { + if !rtio_clocking::crg::check() { host_write(stream, host::Reply::ClockFailure)?; return Err(Error::ClockFailure) } @@ -571,7 +571,7 @@ fn flash_kernel_worker(io: &Io, aux_mutex: &Mutex, return Err(Error::WatchdogExpired(idx)) } - if !rtio_mgt::crg::check() { + if !rtio_clocking::crg::check() { return Err(Error::ClockFailure) }