diff --git a/artiq/firmware/libboard_artiq/hmc542.rs b/artiq/firmware/libboard_artiq/hmc542.rs new file mode 100644 index 000000000..70cd8af54 --- /dev/null +++ b/artiq/firmware/libboard_artiq/hmc542.rs @@ -0,0 +1,54 @@ +use board::{csr, clock}; + +const PIN_LE: u32 = 1 << 0; +const PIN_SIN: u32 = 1 << 1; +const PIN_CLK: u32 = 1 << 2; +const PIN_RST_N: u32 = 1 << 3; +const PIN_RST: u32 = PIN_RST_N; + +const CARDS: usize = 4; +const CHANNELS: usize = 2; + +fn set_pins(card_index: usize, chan_index: usize, pins: u32) { + let pins = pins ^ PIN_RST_N; + let shift = card_index * 2 + chan_index; + unsafe { + let state = csr::allaki_atts::out_read(); + let state = state & !(0xf << shift); + let state = state | (pins << shift); + csr::allaki_atts::out_write(state); + } + clock::spin_us(100); +} + +/// Attenuation is in units of 0.5dB, from 0dB (0) to 31.5dB (63). +pub fn program(card_index: usize, chan_index: usize, atten: u8) { + assert!(card_index < 4 && chan_index < 2); + + // 0b111111 = 1dB + // 0b111110 = 0.5dB + // 0b111101 = 1dB + // ... + // 0b011111 = 16dB + // 0b000000 = 31.5dB + let atten = !(atten << 2); + + let set_pins = |pins| set_pins(card_index, chan_index, pins); + set_pins(PIN_RST); + set_pins(0); + for n in 0..8 { + let sin = if atten & 1 << n != 0 { PIN_SIN } else { 0 }; + set_pins(sin); + set_pins(sin | PIN_CLK); + } + set_pins(PIN_LE); +} + +/// See `program`. +pub fn program_all(atten: u8) { + for card in 0..CARDS { + for chan in 0..CHANNELS { + program(card, chan, atten) + } + } +} diff --git a/artiq/firmware/libboard_artiq/lib.rs b/artiq/firmware/libboard_artiq/lib.rs index 3307681b3..127a55db8 100644 --- a/artiq/firmware/libboard_artiq/lib.rs +++ b/artiq/firmware/libboard_artiq/lib.rs @@ -23,3 +23,5 @@ pub mod hmc830_7043; mod ad9154_reg; #[cfg(has_ad9154)] pub mod ad9154; +#[cfg(has_allaki_atts)] +pub mod hmc542; diff --git a/artiq/firmware/runtime/main.rs b/artiq/firmware/runtime/main.rs index 378d44f07..6ce66595c 100644 --- a/artiq/firmware/runtime/main.rs +++ b/artiq/firmware/runtime/main.rs @@ -95,6 +95,8 @@ fn startup() { board_artiq::hmc830_7043::init().expect("cannot initialize HMC830/7043"); #[cfg(has_ad9154)] board_artiq::ad9154::init().expect("cannot initialize AD9154"); + #[cfg(has_allaki_atts)] + board_artiq::hmc542::program_all(8/*=4dB*/); #[cfg(has_ethmac)] startup_ethernet();