diff --git a/examples/device_db.py b/examples/device_db.py index 105d50f1..c24f5434 100644 --- a/examples/device_db.py +++ b/examples/device_db.py @@ -22,6 +22,13 @@ device_db = { "module": "artiq.coredevice.dma", "class": "CoreDMA" }, + + "i2c_switch": { + "type": "local", + "module": "artiq.coredevice.i2c", + "class": "PCA9548" + }, + # led? are common to all variants "led0": { "type": "local", diff --git a/src/runtime/src/i2c.rs b/src/runtime/src/i2c.rs new file mode 100644 index 00000000..fe585905 --- /dev/null +++ b/src/runtime/src/i2c.rs @@ -0,0 +1,39 @@ +use libboard_zynq; + +static mut I2C_BUS: Option = None; + +pub extern fn start(_busno: i32) { + unsafe { + (&mut I2C_BUS).as_mut().unwrap().start().expect("I2C start failed") + } +} + +pub extern fn restart(_busno: i32) { + unsafe { + (&mut I2C_BUS).as_mut().unwrap().restart().expect("I2C restart failed") + } +} + +pub extern fn stop(_busno: i32) { + unsafe { + (&mut I2C_BUS).as_mut().unwrap().stop().expect("I2C stop failed") + } +} + +pub extern fn write(_busno: i32, data: i32) -> bool { + unsafe { + (&mut I2C_BUS).as_mut().unwrap().write(data as u8).expect("I2C write failed") + } +} + +pub extern fn read(_busno: i32, ack: bool) -> i32 { + unsafe { + (&mut I2C_BUS).as_mut().unwrap().read(ack).expect("I2C read failed") as i32 + } +} + +pub fn init() { + let mut i2c = libboard_zynq::i2c::I2c::i2c0(); + i2c.init().expect("I2C bus initialization failed"); + unsafe { I2C_BUS = Some(i2c) }; +} diff --git a/src/runtime/src/kernel/api.rs b/src/runtime/src/kernel/api.rs index 65e76cae..28ecef42 100644 --- a/src/runtime/src/kernel/api.rs +++ b/src/runtime/src/kernel/api.rs @@ -9,6 +9,7 @@ use alloc::vec; use crate::eh_artiq; use crate::rtio; +use crate::i2c; use super::rpc::{rpc_send, rpc_send_async, rpc_recv}; use super::dma; use super::cache; @@ -100,6 +101,13 @@ pub fn resolve(required: &[u8]) -> Option { api!(cache_get = cache::get), api!(cache_put = cache::put), + // i2c + api!(i2c_start = i2c::start), + api!(i2c_restart = i2c::restart), + api!(i2c_stop = i2c::stop), + api!(i2c_write = i2c::write), + api!(i2c_read = i2c::read), + // Double-precision floating-point arithmetic helper functions // RTABI chapter 4.1.2, Table 2 api!(__aeabi_dadd), diff --git a/src/runtime/src/main.rs b/src/runtime/src/main.rs index dc118dc4..eca4b217 100644 --- a/src/runtime/src/main.rs +++ b/src/runtime/src/main.rs @@ -43,6 +43,7 @@ mod logger; mod mgmt; mod analyzer; mod irq; +mod i2c; fn init_gateware() { // Set up PS->PL clocks @@ -177,6 +178,9 @@ pub fn main_core0() { init_gateware(); info!("detected gateware: {}", identifier_read(&mut [0; 64])); + + i2c::init(); + let cfg = match Config::new() { Ok(cfg) => cfg, Err(err) => {