From f60893c6563bad3f8e9fec60df93a6bc93840029 Mon Sep 17 00:00:00 2001 From: mwojcik Date: Fri, 25 Feb 2022 17:20:34 +0800 Subject: [PATCH 1/3] expose pca954x_select api --- src/libboard_artiq/src/drtioaux_proto.rs | 16 ++++++++++++++++ src/runtime/src/i2c.rs | 12 ++++++++++++ src/runtime/src/kernel/api.rs | 1 + src/satman/src/main.rs | 6 ++++++ 4 files changed, 35 insertions(+) diff --git a/src/libboard_artiq/src/drtioaux_proto.rs b/src/libboard_artiq/src/drtioaux_proto.rs index 62523d6..3cc8118 100644 --- a/src/libboard_artiq/src/drtioaux_proto.rs +++ b/src/libboard_artiq/src/drtioaux_proto.rs @@ -47,6 +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 }, SpiSetConfigRequest { destination: u8, busno: u8, flags: u8, length: u8, div: u8, cs: u8 }, SpiWriteRequest { destination: u8, busno: u8, data: u32 }, @@ -152,6 +153,13 @@ impl Packet { 0x87 => Packet::I2cBasicReply { succeeded: reader.read_bool()? }, + 0x88 => Packet::I2cPca954xSelectRequest { + destination: reader.read_u8()?, + busno: reader.read_u8()?, + address: reader.read_u8()?, + channel: reader.read_u8()?, + clear: reader.read_bool()? + }, 0x90 => Packet::SpiSetConfigRequest { destination: reader.read_u8()?, @@ -301,6 +309,14 @@ impl Packet { writer.write_u8(0x87)?; writer.write_bool(succeeded)?; }, + Packet::I2cPca954xSelectRequest { destination, busno, address, channel, clear } => { + writer.write_u8(0x88)?; + writer.write_u8(destination)?; + writer.write_u8(busno)?; + writer.write_u8(address)?; + writer.write_u8(channel)?; + writer.write_bool(clear)?; + }, Packet::SpiSetConfigRequest { destination, busno, flags, length, div, cs } => { writer.write_u8(0x90)?; diff --git a/src/runtime/src/i2c.rs b/src/runtime/src/i2c.rs index b8c5bcf..42f19a9 100644 --- a/src/runtime/src/i2c.rs +++ b/src/runtime/src/i2c.rs @@ -60,6 +60,18 @@ pub extern fn read(busno: i32, ack: bool) -> i32 { } } +pub extern fn pca954x_select(busno: i32, address: i32, channel: i32, clear: bool) { + if busno > 0 { + artiq_raise!("I2CError", "I2C bus could not be accessed"); + } + unsafe { + let ch = if clear { None } else { Some(channel as u8) }; + if (&mut I2C_BUS).as_mut().unwrap().pca954x_select(address as u8, ch).is_err() { + artiq_raise!("I2CError", "PCA954X select failed"); + } + } +} + pub fn init() { let mut i2c = libboard_zynq::i2c::I2c::i2c0(); i2c.init().expect("I2C bus initialization failed"); diff --git a/src/runtime/src/kernel/api.rs b/src/runtime/src/kernel/api.rs index a234c8b..bf07008 100644 --- a/src/runtime/src/kernel/api.rs +++ b/src/runtime/src/kernel/api.rs @@ -116,6 +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), // 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 69693a1..1a75e64 100644 --- a/src/satman/src/main.rs +++ b/src/satman/src/main.rs @@ -282,6 +282,12 @@ 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 } => { + 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(); + drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded }) + } drtioaux::Packet::SpiSetConfigRequest { destination: _destination, busno: _busno, flags: _flags, length: _length, div: _div, cs: _cs } => { -- 2.42.0 From b462a968bf8f2614227ade897a7bb5476d0b9c6e Mon Sep 17 00:00:00 2001 From: spaqin Date: Tue, 1 Mar 2022 14:52:23 +0800 Subject: [PATCH 2/3] i2c: update api to mainline --- src/libboard_artiq/src/drtioaux_proto.rs | 12 +++++------- src/runtime/src/i2c.rs | 17 ++++++++++++++--- src/runtime/src/kernel/api.rs | 2 +- src/satman/src/main.rs | 17 ++++++++++++++--- 4 files changed, 34 insertions(+), 14 deletions(-) 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 }) } -- 2.42.0 From 710d6624a110eec2f16b599c33ca53ed7e0b05a9 Mon Sep 17 00:00:00 2001 From: spaqin Date: Wed, 2 Mar 2022 10:49:22 +0800 Subject: [PATCH 3/3] i2c: move match outside unsafe, remove return --- src/libboard_artiq/src/drtioaux_proto.rs | 2 +- src/runtime/src/i2c.rs | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/libboard_artiq/src/drtioaux_proto.rs b/src/libboard_artiq/src/drtioaux_proto.rs index c83da1d..e2fee29 100644 --- a/src/libboard_artiq/src/drtioaux_proto.rs +++ b/src/libboard_artiq/src/drtioaux_proto.rs @@ -308,7 +308,7 @@ impl Packet { writer.write_u8(0x87)?; writer.write_bool(succeeded)?; }, - Packet::I2cPca954xSelectRequest { destination, busno, address, mask } => { + Packet::I2cSwitchSelectRequest { destination, busno, address, mask } => { writer.write_u8(0x88)?; writer.write_u8(destination)?; writer.write_u8(busno)?; diff --git a/src/runtime/src/i2c.rs b/src/runtime/src/i2c.rs index b2c166f..de908f3 100644 --- a/src/runtime/src/i2c.rs +++ b/src/runtime/src/i2c.rs @@ -64,19 +64,19 @@ pub extern fn switch_select(busno: i32, address: i32, mask: i32) { if busno > 0 { artiq_raise!("I2CError", "I2C bus could not be accessed"); } + 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") + }; unsafe { - 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", "switch select failed"); } -- 2.42.0