diff --git a/artiq/firmware/libboard_misoc/io_expander.rs b/artiq/firmware/libboard_misoc/io_expander.rs index edf2ce666..7009e0476 100644 --- a/artiq/firmware/libboard_misoc/io_expander.rs +++ b/artiq/firmware/libboard_misoc/io_expander.rs @@ -81,6 +81,32 @@ impl IoExpander { Ok(io_expander) } + #[cfg(soc_platform = "efc")] + pub fn new() -> Result { + // TODO: Put Virtual User LEDs L0 L1 in gateware + const VIRTUAL_LED_MAPPING: [(u8, u8, u8); 2] = [(0, 0, 5), (1, 0, 6)]; + + let mut io_expander = IoExpander { + busno: 0, + port: 1, + address: 0x40, + virtual_led_mapping: &VIRTUAL_LED_MAPPING, + iodir: [0xff; 2], + out_current: [0; 2], + out_target: [0; 2], + registers: Registers { + iodira: 0x00, + iodirb: 0x01, + gpioa: 0x12, + gpiob: 0x13, + }, + }; + if !io_expander.check_ack()? { + return Err("MCP23017 io expander not found."); + }; + Ok(io_expander) + } + #[cfg(soc_platform = "kasli")] fn select(&self) -> Result<(), &'static str> { let mask: u16 = 1 << self.port; @@ -89,6 +115,13 @@ impl IoExpander { Ok(()) } + #[cfg(soc_platform = "efc")] + fn select(&self) -> Result<(), &'static str> { + let mask: u16 = 1 << self.port; + i2c::switch_select(self.busno, 0x70, mask as u8)?; + Ok(()) + } + fn write(&self, addr: u8, value: u8) -> Result<(), &'static str> { i2c::start(self.busno)?; i2c::write(self.busno, self.address)?; diff --git a/artiq/firmware/libboard_misoc/lib.rs b/artiq/firmware/libboard_misoc/lib.rs index 3189ccfcd..7ba835dcf 100644 --- a/artiq/firmware/libboard_misoc/lib.rs +++ b/artiq/firmware/libboard_misoc/lib.rs @@ -40,7 +40,7 @@ pub mod ethmac; pub mod i2c; #[cfg(soc_platform = "kasli")] pub mod i2c_eeprom; -#[cfg(all(soc_platform = "kasli", hw_rev = "v2.0"))] +#[cfg(any(all(soc_platform = "kasli", hw_rev = "v2.0"), soc_platform = "efc"))] pub mod io_expander; #[cfg(all(has_ethmac, feature = "smoltcp"))] pub mod net_settings; diff --git a/artiq/firmware/satman/main.rs b/artiq/firmware/satman/main.rs index 4e9f8fa33..cd101d28c 100644 --- a/artiq/firmware/satman/main.rs +++ b/artiq/firmware/satman/main.rs @@ -529,6 +529,19 @@ pub extern fn main() -> i32 { sysclk_setup(); + #[cfg(soc_platform = "efc")] + { + let mut io_expander = board_misoc::io_expander::IoExpander::new().unwrap(); + // Enable VADJ and P3V3_FMC + io_expander.set_oe(1, 1 << 0 | 1 << 1).unwrap(); + + io_expander.set(1, 0, true); + io_expander.set(1, 1, true); + + io_expander.service().unwrap(); + } + + #[cfg(not(soc_platform = "efc"))] unsafe { csr::drtio_transceiver::txenable_write(0xffffffffu32 as _); }