84 lines
2.1 KiB
Rust
84 lines
2.1 KiB
Rust
use libboard_zynq;
|
|
|
|
pub static mut I2C_BUS: Option<libboard_zynq::i2c::I2c> = None;
|
|
|
|
pub fn start() -> Result<(), &'static str> {
|
|
unsafe {
|
|
if (&mut I2C_BUS).as_mut().unwrap().start().is_err() {
|
|
Err("I2C start failed")
|
|
} else {
|
|
Ok(())
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn restart() -> Result<(), &'static str> {
|
|
unsafe {
|
|
if (&mut I2C_BUS).as_mut().unwrap().restart().is_err() {
|
|
Err("I2C restart failed")
|
|
} else {
|
|
Ok(())
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn stop() -> Result<(), &'static str> {
|
|
unsafe {
|
|
if (&mut I2C_BUS).as_mut().unwrap().stop().is_err() {
|
|
Err("I2C stop failed")
|
|
} else {
|
|
Ok(())
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn write(data: i32) -> Result<bool, &'static str> {
|
|
unsafe {
|
|
match (&mut I2C_BUS).as_mut().unwrap().write(data as u8) {
|
|
Ok(r) =>Ok(r),
|
|
Err(_) => Err("I2C write failed"),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn read(ack: bool) -> Result<i32, &'static str> {
|
|
unsafe {
|
|
match (&mut I2C_BUS).as_mut().unwrap().read(ack) {
|
|
Ok(r) => Ok(r as i32),
|
|
Err(_) => Err("I2C read failed"),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn pca954x_select(address: i32, channel: Option<u8>) -> Result<(), &'static str> {
|
|
unsafe {
|
|
if (&mut I2C_BUS).as_mut().unwrap().pca954x_select(address as u8, channel).is_err() {
|
|
Err("switch select failed")
|
|
} else {
|
|
Ok(())
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn switch_select(address: i32, mask: i32) -> Result<(), &'static str> {
|
|
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),
|
|
_ => return Err("switch select supports only one channel")
|
|
};
|
|
pca954x_select(address, ch)
|
|
}
|
|
|
|
pub fn init() {
|
|
let mut i2c = libboard_zynq::i2c::I2c::i2c0();
|
|
i2c.init().expect("I2C bus initialization failed");
|
|
unsafe { I2C_BUS = Some(i2c) };
|
|
}
|