From a421820a32d0ba2de94fea3e258aa45d883d4d6e Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sun, 6 Oct 2019 21:42:45 +0800 Subject: [PATCH] sayma: initialize DACs over DRTIO --- artiq/firmware/libboard_artiq/ad9154.rs | 4 +- artiq/firmware/libboard_artiq/jdcg.rs | 12 ++-- .../firmware/libproto_artiq/drtioaux_proto.rs | 21 +++++++ artiq/firmware/satman/main.rs | 56 ++++++++++++++++++- artiq/firmware/satman/repeater.rs | 4 ++ 5 files changed, 88 insertions(+), 9 deletions(-) diff --git a/artiq/firmware/libboard_artiq/ad9154.rs b/artiq/firmware/libboard_artiq/ad9154.rs index 86de3dbee..479d62f41 100644 --- a/artiq/firmware/libboard_artiq/ad9154.rs +++ b/artiq/firmware/libboard_artiq/ad9154.rs @@ -350,11 +350,11 @@ pub fn setup(dacno: u8, linerate: u64) -> Result<(), &'static str> { 0x1*ad9154_reg::LINK_EN | 0*ad9154_reg::LINK_PAGE | 0*ad9154_reg::LINK_MODE | 0*ad9154_reg::CHECKSUM_MODE); info!(" ...done"); + status(dacno); Ok(()) } -#[allow(dead_code)] -fn status(dacno: u8) { +pub fn status(dacno: u8) { spi_setup(dacno); info!("SERDES_PLL_LOCK: {}", (read(ad9154_reg::PLL_STATUS) & ad9154_reg::SERDES_PLL_LOCK_RB)); diff --git a/artiq/firmware/libboard_artiq/jdcg.rs b/artiq/firmware/libboard_artiq/jdcg.rs index b93d28336..dfb0d8632 100644 --- a/artiq/firmware/libboard_artiq/jdcg.rs +++ b/artiq/firmware/libboard_artiq/jdcg.rs @@ -2,35 +2,35 @@ use board_misoc::csr; pub fn jesd_reset(reset: bool) { unsafe { - csr::jesd_crg::jreset_write(if reset {1} else {0}); + csr::jesd_crg::jreset_write(if reset {1} else {0}); } } -fn jesd_enable(dacno: u8, en: bool) { +pub fn jesd_enable(dacno: u8, en: bool) { unsafe { (csr::JDCG[dacno as usize].jesd_control_enable_write)(if en {1} else {0}) } } -fn jesd_ready(dacno: u8) -> bool { +pub fn jesd_ready(dacno: u8) -> bool { unsafe { (csr::JDCG[dacno as usize].jesd_control_ready_read)() != 0 } } -fn jesd_prbs(dacno: u8, en: bool) { +pub fn jesd_prbs(dacno: u8, en: bool) { unsafe { (csr::JDCG[dacno as usize].jesd_control_prbs_config_write)(if en {0b01} else {0b00}) } } -fn jesd_stpl(dacno: u8, en: bool) { +pub fn jesd_stpl(dacno: u8, en: bool) { unsafe { (csr::JDCG[dacno as usize].jesd_control_stpl_enable_write)(if en {1} else {0}) } } -fn jesd_jsync(dacno: u8) -> bool { +pub fn jesd_jsync(dacno: u8) -> bool { unsafe { (csr::JDCG[dacno as usize].jesd_control_jsync_read)() != 0 } diff --git a/artiq/firmware/libproto_artiq/drtioaux_proto.rs b/artiq/firmware/libproto_artiq/drtioaux_proto.rs index 64e279614..092e6fb4d 100644 --- a/artiq/firmware/libproto_artiq/drtioaux_proto.rs +++ b/artiq/firmware/libproto_artiq/drtioaux_proto.rs @@ -53,6 +53,9 @@ pub enum Packet { SpiReadRequest { destination: u8, busno: u8 }, SpiReadReply { succeeded: bool, data: u32 }, SpiBasicReply { succeeded: bool }, + + JdacSetupRequest { destination: u8, dacno: u8 }, + JdacBasicReply { succeeded: bool }, } impl Packet { @@ -178,6 +181,14 @@ impl Packet { succeeded: reader.read_bool()? }, + 0xa0 => Packet::JdacSetupRequest { + destination: reader.read_u8()?, + dacno: reader.read_u8()?, + }, + 0xa1 => Packet::JdacBasicReply { + succeeded: reader.read_bool()? + }, + ty => return Err(Error::UnknownPacket(ty)) }) } @@ -329,6 +340,16 @@ impl Packet { writer.write_u8(0x95)?; writer.write_bool(succeeded)?; }, + + Packet::JdacSetupRequest { destination, dacno } => { + writer.write_u8(0xa0)?; + writer.write_u8(destination)?; + writer.write_u8(dacno)?; + } + Packet::JdacBasicReply { succeeded } => { + writer.write_u8(0xa1)?; + writer.write_bool(succeeded)?; + }, } Ok(()) } diff --git a/artiq/firmware/satman/main.rs b/artiq/firmware/satman/main.rs index e9cc3c1ed..0434168bf 100644 --- a/artiq/firmware/satman/main.rs +++ b/artiq/firmware/satman/main.rs @@ -288,6 +288,22 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater], } } + drtioaux::Packet::JdacSetupRequest { destination: _destination, dacno: _dacno } => { + forward!(_routing_table, _destination, *_rank, _repeaters, &packet); + #[cfg(has_ad9154)] + let succeeded = { + #[cfg(rtio_frequency = "125.0")] + const LINERATE: u64 = 5_000_000_000; + #[cfg(rtio_frequency = "150.0")] + const LINERATE: u64 = 6_000_000_000; + board_artiq::ad9154::setup(_dacno, LINERATE).is_ok() + }; + #[cfg(not(has_ad9154))] + let succeeded = false; + drtioaux::send(0, + &drtioaux::Packet::JdacBasicReply { succeeded: succeeded }) + } + _ => { warn!("received unexpected aux packet"); Ok(()) @@ -400,6 +416,32 @@ const SI5324_SETTINGS: si5324::FrequencySettings crystal_ref: true }; +#[cfg(has_jdcg)] +fn init_jdcgs() { + for dacno in 0..csr::JDCG.len() { + let dacno = dacno as u8; + info!("DAC-{} initializing...", dacno); + board_artiq::jdcg::jesd_enable(dacno, false); + board_artiq::jdcg::jesd_prbs(dacno, false); + board_artiq::jdcg::jesd_stpl(dacno, false); + clock::spin_us(10000); + board_artiq::jdcg::jesd_enable(dacno, true); + if let Err(e) = drtioaux::send(1, &drtioaux::Packet::JdacSetupRequest { + destination: 0, + dacno: dacno + }) { + error!("aux packet error ({})", e); + } + match drtioaux::recv_timeout(1, Some(1000)) { + Ok(drtioaux::Packet::JdacBasicReply { succeeded }) => + if !succeeded { error!("DAC-{} initialization failed", dacno); }, + Ok(packet) => error!("received unexpected aux packet: {:?}", packet), + Err(e) => error!("aux packet error ({})", e), + } + info!(" ...done"); + } +} + #[no_mangle] pub extern fn main() -> i32 { clock::init(); @@ -473,19 +515,31 @@ pub extern fn main() -> i32 { * Si5324 is locked to the recovered clock. */ board_artiq::jdcg::jesd_reset(false); - // TODO: board_artiq::ad9154::init(); + if repeaters[0].is_up() { + init_jdcgs(); + } } drtioaux::reset(0); drtiosat_reset(false); drtiosat_reset_phy(false); + #[cfg(has_jdcg)] + let mut rep0_was_up = repeaters[0].is_up(); while drtiosat_link_rx_up() { drtiosat_process_errors(); process_aux_packets(&mut repeaters, &mut routing_table, &mut rank); for mut rep in repeaters.iter_mut() { rep.service(&routing_table, rank); } + #[cfg(has_jdcg)] + { + let rep0_is_up = repeaters[0].is_up(); + if rep0_is_up && !rep0_was_up { + init_jdcgs(); + } + rep0_was_up = rep0_is_up; + } hardware_tick(&mut hardware_tick_ts); if drtiosat_tsc_loaded() { info!("TSC loaded from uplink"); diff --git a/artiq/firmware/satman/repeater.rs b/artiq/firmware/satman/repeater.rs index f51d413aa..69a813d34 100644 --- a/artiq/firmware/satman/repeater.rs +++ b/artiq/firmware/satman/repeater.rs @@ -43,6 +43,10 @@ impl Repeater { } } + pub fn is_up(&self) -> bool { + self.state == RepeaterState::Up + } + pub fn service(&mut self, routing_table: &drtio_routing::RoutingTable, rank: u8) { self.process_local_errors();