From ccb140a9298e2ff7eb7727f34e6492a71256d151 Mon Sep 17 00:00:00 2001 From: linuswck Date: Mon, 4 Sep 2023 16:50:00 +0800 Subject: [PATCH] Firmware: Add AD9117 DAC Startup Seq for shuttler --- artiq/firmware/libboard_artiq/ad9117.rs | 70 +++++++++++++++++++++++++ artiq/firmware/libboard_artiq/lib.rs | 3 ++ artiq/firmware/libboard_artiq/spi.rs | 14 ++--- artiq/firmware/satman/main.rs | 5 ++ 4 files changed, 86 insertions(+), 6 deletions(-) create mode 100644 artiq/firmware/libboard_artiq/ad9117.rs diff --git a/artiq/firmware/libboard_artiq/ad9117.rs b/artiq/firmware/libboard_artiq/ad9117.rs new file mode 100644 index 000000000..4c152e976 --- /dev/null +++ b/artiq/firmware/libboard_artiq/ad9117.rs @@ -0,0 +1,70 @@ +use spi; +use board_misoc::{csr, clock}; + +const DATA_CTRL_REG : u8 = 0x02; +const IRCML_REG : u8 = 0x05; +const QRCML_REG : u8 = 0x08; +const CLKMODE_REG : u8 = 0x14; +const VERSION_REG : u8 = 0x1F; + +fn hard_reset() { + unsafe { + // Min Pulse Width: 50ns + csr::dac_rst::out_write(1); + clock::spin_us(1); + csr::dac_rst::out_write(0); + } +} + +fn spi_setup(dac_sel: u8, half_duplex: bool, end: bool) -> Result<(), &'static str> { + // Clear the cs_polarity and cs config + spi::set_config(0, 0, 8, 64, 0b1111)?; + spi::set_config(0, 1 << 3, 8, 64, (7 - dac_sel) << 1)?; + spi::set_config(0, (half_duplex as u8) << 7 | (end as u8) << 1, 8, 64, 0b0001)?; + Ok(()) +} + +fn write(dac_sel: u8, reg: u8, val: u8) -> Result<(), &'static str> { + spi_setup(dac_sel, false, false)?; + spi::write(0, (reg as u32) << 24)?; + spi_setup(dac_sel, false, true)?; + spi::write(0, (val as u32) << 24)?; + + Ok(()) +} + +fn read(dac_sel: u8, reg: u8) -> Result { + spi_setup(dac_sel, false, false)?; + spi::write(0, ((reg | 1 << 7) as u32) << 24)?; + spi_setup(dac_sel, true, true)?; + spi::write(0, 0)?; + + Ok(spi::read(0)? as u8) +} + +pub fn init() -> Result<(), &'static str> { + hard_reset(); + + for channel in 0..8 { + let reg = read(channel, VERSION_REG)?; + if reg != 0x0A { + debug!("DAC AD9117 Channel {} has incorrect hardware version. VERSION reg: {:02x}", channel, reg); + return Err("DAC AD9117 hardware version is not equal to 0x0A"); + } + let reg = read(channel, CLKMODE_REG)?; + if reg >> 4 & 1 != 0 { + debug!("DAC AD9117 Channel {} retiming fails. CLKMODE reg: {:02x}", channel, reg); + return Err("DAC AD9117 retiming failure"); + } + + // Set the DACs input data format to be twos complement + // Set IFIRST and IRISING to True + write(channel, DATA_CTRL_REG, 1 << 7 | 1 << 5 | 1 << 4)?; + + // Enable internal common mode resistors of both channels + write(channel, IRCML_REG, 1 << 7)?; + write(channel, QRCML_REG, 1 << 7)?; + } + + Ok(()) +} diff --git a/artiq/firmware/libboard_artiq/lib.rs b/artiq/firmware/libboard_artiq/lib.rs index 9579acaaa..f564c98e4 100644 --- a/artiq/firmware/libboard_artiq/lib.rs +++ b/artiq/firmware/libboard_artiq/lib.rs @@ -34,3 +34,6 @@ pub mod drtio_routing; #[cfg(all(has_drtio_eem, feature = "alloc"))] pub mod drtio_eem; + +#[cfg(soc_platform = "efc")] +pub mod ad9117; diff --git a/artiq/firmware/libboard_artiq/spi.rs b/artiq/firmware/libboard_artiq/spi.rs index 78556b24b..3464580a3 100644 --- a/artiq/firmware/libboard_artiq/spi.rs +++ b/artiq/firmware/libboard_artiq/spi.rs @@ -2,9 +2,11 @@ mod imp { use board_misoc::csr; - pub fn set_config(busno: u8, flags: u8, length: u8, div: u8, cs: u8) -> Result<(), ()> { + const INVALID_BUS: &'static str = "Invalid SPI bus"; + + pub fn set_config(busno: u8, flags: u8, length: u8, div: u8, cs: u8) -> Result<(), &'static str> { if busno != 0 { - return Err(()) + return Err(INVALID_BUS) } unsafe { while csr::converter_spi::writable_read() == 0 {} @@ -31,9 +33,9 @@ mod imp { Ok(()) } - pub fn write(busno: u8, data: u32) -> Result<(), ()> { + pub fn write(busno: u8, data: u32) -> Result<(), &'static str> { if busno != 0 { - return Err(()) + return Err(INVALID_BUS) } unsafe { while csr::converter_spi::writable_read() == 0 {} @@ -42,9 +44,9 @@ mod imp { Ok(()) } - pub fn read(busno: u8) -> Result { + pub fn read(busno: u8) -> Result { if busno != 0 { - return Err(()) + return Err(INVALID_BUS) } Ok(unsafe { while csr::converter_spi::writable_read() == 0 {} diff --git a/artiq/firmware/satman/main.rs b/artiq/firmware/satman/main.rs index 35d2922ee..6eb1c7d9d 100644 --- a/artiq/firmware/satman/main.rs +++ b/artiq/firmware/satman/main.rs @@ -15,6 +15,8 @@ use board_misoc::{csr, ident, clock, uart_logger, i2c, pmp}; #[cfg(has_si5324)] use board_artiq::si5324; use board_artiq::{spi, drtioaux}; +#[cfg(soc_platform = "efc")] +use board_artiq::ad9117; use board_artiq::drtio_routing; use proto_artiq::drtioaux_proto::ANALYZER_MAX_SIZE; #[cfg(has_drtio_eem)] @@ -578,6 +580,9 @@ pub extern fn main() -> i32 { let mut hardware_tick_ts = 0; + #[cfg(soc_platform = "efc")] + ad9117::init().expect("AD9117 initialization failed"); + loop { while !drtiosat_link_rx_up() { drtiosat_process_errors();