diff --git a/src/libboard_artiq/src/drtioaux_proto.rs b/src/libboard_artiq/src/drtioaux_proto.rs index 3cc8118..c83da1d 100644 --- a/src/libboard_artiq/src/drtioaux_proto.rs +++ b/src/libboard_artiq/src/drtioaux_proto.rs @@ -47,7 +47,7 @@ pub enum Packet { I2cReadRequest { destination: u8, busno: u8, ack: bool }, I2cReadReply { succeeded: bool, data: u8 }, I2cBasicReply { succeeded: bool }, - I2cPca954xSelectRequest { destination: u8, busno: u8, address: u8, channel: u8, clear: bool }, + I2cSwitchSelectRequest { destination: u8, busno: u8, address: u8, mask: u8 }, SpiSetConfigRequest { destination: u8, busno: u8, flags: u8, length: u8, div: u8, cs: u8 }, SpiWriteRequest { destination: u8, busno: u8, data: u32 }, @@ -153,12 +153,11 @@ impl Packet { 0x87 => Packet::I2cBasicReply { succeeded: reader.read_bool()? }, - 0x88 => Packet::I2cPca954xSelectRequest { + 0x88 => Packet::I2cSwitchSelectRequest { destination: reader.read_u8()?, busno: reader.read_u8()?, address: reader.read_u8()?, - channel: reader.read_u8()?, - clear: reader.read_bool()? + mask: reader.read_u8()? }, 0x90 => Packet::SpiSetConfigRequest { @@ -309,13 +308,12 @@ impl Packet { writer.write_u8(0x87)?; writer.write_bool(succeeded)?; }, - Packet::I2cPca954xSelectRequest { destination, busno, address, channel, clear } => { + Packet::I2cPca954xSelectRequest { destination, busno, address, mask } => { writer.write_u8(0x88)?; writer.write_u8(destination)?; writer.write_u8(busno)?; writer.write_u8(address)?; - writer.write_u8(channel)?; - writer.write_bool(clear)?; + writer.write_u8(mask)?; }, Packet::SpiSetConfigRequest { destination, busno, flags, length, div, cs } => { diff --git a/src/runtime/src/i2c.rs b/src/runtime/src/i2c.rs index 42f19a9..b2c166f 100644 --- a/src/runtime/src/i2c.rs +++ b/src/runtime/src/i2c.rs @@ -60,14 +60,25 @@ pub extern fn read(busno: i32, ack: bool) -> i32 { } } -pub extern fn pca954x_select(busno: i32, address: i32, channel: i32, clear: bool) { +pub extern fn switch_select(busno: i32, address: i32, mask: i32) { if busno > 0 { artiq_raise!("I2CError", "I2C bus could not be accessed"); } unsafe { - let ch = if clear { None } else { Some(channel as u8) }; + let ch = match mask { //decode from mainline, PCA9548-centric API + 0x00 => None, + 0x01 => Some(0), + 0x02 => Some(1), + 0x04 => Some(2), + 0x08 => Some(3), + 0x10 => Some(4), + 0x20 => Some(5), + 0x40 => Some(6), + 0x80 => Some(7), + _ => { artiq_raise!("I2CError", "switch select supports only one channel"); return } + }; if (&mut I2C_BUS).as_mut().unwrap().pca954x_select(address as u8, ch).is_err() { - artiq_raise!("I2CError", "PCA954X select failed"); + artiq_raise!("I2CError", "switch select failed"); } } } diff --git a/src/runtime/src/kernel/api.rs b/src/runtime/src/kernel/api.rs index bf07008..122c7bb 100644 --- a/src/runtime/src/kernel/api.rs +++ b/src/runtime/src/kernel/api.rs @@ -116,7 +116,7 @@ pub fn resolve(required: &[u8]) -> Option { api!(i2c_stop = i2c::stop), api!(i2c_write = i2c::write), api!(i2c_read = i2c::read), - api!(i2c_pca954x_select = i2c::pca954x_select), + api!(i2c_switch_select = i2c::switch_select), // Double-precision floating-point arithmetic helper functions // RTABI chapter 4.1.2, Table 2 diff --git a/src/satman/src/main.rs b/src/satman/src/main.rs index 1a75e64..f8915d7 100644 --- a/src/satman/src/main.rs +++ b/src/satman/src/main.rs @@ -282,10 +282,21 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater], &drtioaux::Packet::I2cReadReply { succeeded: false, data: 0xff }) } } - drtioaux::Packet::I2cStartRequest { destination: _destination, busno: _busno, address, channel, clear } => { + drtioaux::Packet::I2cSwitchSelectRequest { destination: _destination, busno: _busno, address, mask } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet, timer); - let ch = if clear { None } else { Some(channel as u8) }; - let succeeded = i2c.pca954x_select(address, channel).is_ok(); + ch = match mask { //decode from mainline, PCA9548-centric API + 0x00 => None, + 0x01 => Some(0), + 0x02 => Some(1), + 0x04 => Some(2), + 0x08 => Some(3), + 0x10 => Some(4), + 0x20 => Some(5), + 0x40 => Some(6), + 0x80 => Some(7), + _ => { return drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: false }); } + }; + let succeeded = i2c.pca954x_select(address, ch).is_ok(); drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded }) }