diff --git a/Cargo.toml b/Cargo.toml index 2a66b46..6155e48 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tof-control" -version = "1.0.5" +version = "1.10.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -8,6 +8,10 @@ edition = "2021" [profile.release] opt-level = "z" +[[bin]] +name = "calib-simulator" +path = "src/bin/dev/calib_simulator.rs" + [[bin]] name = "rat-control" path = "src/bin/rat_control.rs" @@ -26,12 +30,11 @@ path = "src/bin/rat_tui.rs" [[bin]] name = "rb-mode" -path = "src/bin/rb_mode.rs" +path = "src/bin/dev/rb_mode.rs" [[bin]] name = "rb-dac" -path = "src/bin/rb_dac.rs" - +path = "src/bin/dev/rb_dac.rs" [[bin]] name = "cpu-control" path = "src/bin/cpu_control.rs" @@ -54,7 +57,8 @@ indicatif = "0.17.7" chrono-tz = "0.8.4" ratatui = "0.25.0" crossterm = "0.27.0" +once_cell = "1.21.3" [build-dependencies] bindgen = "0.64.0" -cc = "1.0.79" \ No newline at end of file +cc = "1.0.79" diff --git a/src/bin/rb_dac.rs b/src/bin/rb_dac.rs deleted file mode 100644 index 0915c9a..0000000 --- a/src/bin/rb_dac.rs +++ /dev/null @@ -1,57 +0,0 @@ -use clap::Parser; - -use tof_control::rb_control::rb_dac; - -#[derive(Parser, Debug)] -#[command(author = "Takeru Hayashi", version, about, long_about = None)] -struct Cli { - #[clap(short, long, help = "Set all DAC outputs to defatult values")] - set: bool, - #[clap(short, long, help = "Read all DAC output values")] - read: bool, - #[clap(long, help = "Reset all DAC outputs values to zero")] - reset: bool, - #[arg(short, long, help = "Verbose mode")] - verbose: bool, -} - -fn main() { - let cli = Cli::parse(); - - if cli.set { - match rb_dac::set_dac() { - Ok(_) => { - println!("All DAC outputs are set to default values.") - } - Err(e) => { - eprintln!("Error: {:?}", e); - } - } - std::process::exit(0); - }else if cli.read { - match rb_dac::read_dac() { - Ok(dac_values) => { - for (channel, dac) in dac_values.iter().enumerate() { - println!("DAC Channel {} Value: {}", channel, dac); - } - } - Err(e) => { - eprintln!("Error: {:?}", e); - } - } - std::process::exit(0); - } else if cli.reset { - match rb_dac::zero_dac() { - Ok(_) => { - println!("All DAC outputs are reset to 0mV.") - } - Err(e) => { - eprintln!("Error: {:?}", e); - } - } - std::process::exit(0); - } else { - println!("No valid option provided. Use --help for more information."); - std::process::exit(1); - } -} \ No newline at end of file diff --git a/src/bin/rb_mode.rs b/src/bin/rb_mode.rs deleted file mode 100644 index 5dbb34f..0000000 --- a/src/bin/rb_mode.rs +++ /dev/null @@ -1,213 +0,0 @@ -use clap::{Parser, Subcommand, ValueEnum}; - -use tof_control::rb_control::{rb_mode, rb_dac}; - -#[derive(Parser, Debug)] -#[command(author = "Takeru Hayashi", version, about, long_about = None)] -struct Cli { - #[clap(subcommand)] - command: Commands, - #[arg(short, long, help = "Verbose mode")] - verbose: bool, -} - -#[derive(Subcommand, Debug)] -enum Commands { - #[clap(short_flag = 's')] - Set { - #[arg(ignore_case = true, value_enum)] - mode: Mode, - }, - #[clap(short_flag = 'r')] - Read { - }, - Verify { - #[arg(ignore_case = true, value_enum)] - mode: Mode, - }, - #[clap(short_flag = 't')] - Test { - }, -} - -#[derive(ValueEnum, Clone, Debug)] -enum Mode { - NOI, - VCAL, - TCAL, - SMA, -} -fn main() { - let cli = Cli::parse(); - - match cli.command { - Commands::Set { mode } => { - match mode { - Mode::NOI => { - match rb_mode::select_noi_mode() { - Ok(_) => { println!("RB is now NOI mode.") } - Err(e) => { eprintln!("Mode select error: {}", e) } - } - } - Mode::VCAL => { - match rb_mode::select_vcal_mode() { - Ok(_) => { println!("RB is now VCAL mode.") } - Err(e) => { eprintln!("Mode select error: {}", e) } - } - } - Mode::TCAL => { - match rb_mode::select_tcal_mode() { - Ok(_) => { println!("RB is now TCAL mode.") } - Err(e) => { eprintln!("Mode select error: {}", e) } - } - } - Mode::SMA => { - match rb_mode::select_sma_mode() { - Ok(_) => { println!("RB is now SMA mode.") } - Err(e) => { eprintln!("Mode select error: {}", e) } - } - } - } - } - Commands::Read { } => { - match rb_mode::read_input_mode() { - Ok(mode) => { - println!("Current mode: {}", mode); - } - Err(e) => { - eprintln!("Error: {:?}", e); - } - } - } - Commands::Verify { mode } => { - match mode { - Mode::NOI => { - match rb_mode::verify_input_mode("NOI") { - Ok(bool) => { - if bool { - println!("RB is in NOI mode."); - } else { - println!("RB is NOT in NOI mode."); - } - } - Err(e) => { - eprintln!("Mode verification error: {:?}", e); - } - } - } - Mode::VCAL => { - match rb_mode::verify_input_mode("VCAL") { - Ok(bool) => { - if bool { - println!("RB is in VCAL mode."); - } else { - println!("RB is NOT in VCAL mode."); - } - } - Err(e) => { - eprintln!("Mode verification error: {:?}", e); - } - } - } - Mode::TCAL => { - match rb_mode::verify_input_mode("TCAL") { - Ok(bool) => { - if bool { - println!("RB is in TCAL mode."); - } else { - println!("RB is NOT in TCAL mode."); - } - } - Err(e) => { - eprintln!("Mode verification error: {:?}", e); - } - } - } - Mode::SMA => { - match rb_mode::verify_input_mode("SMA") { - Ok(bool) => { - if bool { - println!("RB is in SMA mode."); - } else { - println!("RB is NOT in SMA mode."); - } - } - Err(e) => { - eprintln!("Mode verification error: {:?}", e); - } - } - } - } - } - Commands::Test { } => { - match rb_dac::set_single_dac(2, 0) { - Ok(_) => { - println!("DAC DRS ROFS set to 0V for test mode."); - } - Err(e) => { - eprintln!("Error setting test mode: {:?}", e); - } - } - } - } - - // if cli.read { - // match rb_mode::read_input_mode() { - // Ok(mode) => { - // println!("Current mode: {}", mode); - // } - // Err(e) => { - // eprintln!("Error: {:?}", e); - // } - // } - // std::process::exit(0); - // } - - // if cli.verify { - // match rb_mode::verify_input_mode("SMA") { - // Ok(bool) => { - // if bool { - // println!("RB is in the expected input mode."); - // } else { - // println!("RB is NOT in the expected input mode."); - // } - // } - // Err(e) => { - // eprintln!("Mode verification error: {:?}", e); - // } - // } - // } - - // if let Some(mode) = cli.set { - // match mode { - // Mode::NOI => { - // match rb_mode::select_noi_mode() { - // Ok(_) => { println!("RB is now NOI mode.") } - // Err(e) => { eprintln!("Mode select error: {}", e) } - // } - // } - // Mode::VCAL => { - // match rb_mode::select_vcal_mode() { - // Ok(_) => { println!("RB is now VCAL mode.") } - // Err(e) => { eprintln!("Mode select error: {}", e) } - // } - // } - // Mode::TCAL => { - // match rb_mode::select_tcal_mode() { - // Ok(_) => { println!("RB is now TCAL mode.") } - // Err(e) => { eprintln!("Mode select error: {}", e) } - // } - // } - // Mode::SMA => { - // match rb_mode::select_sma_mode() { - // Ok(_) => { println!("RB is now SMA mode.") } - // Err(e) => { eprintln!("Mode select error: {}", e) } - // } - // } - // } - // } else { - // eprintln!("No argument is given."); - // eprintln!("\t-s/--set to set RB input mode from NOI, VCAL, TCAL, and SMA."); - // std::process::exit(-1); - // } -} \ No newline at end of file diff --git a/src/cpc_control/cpc_temp.rs b/src/cpc_control/cpc_temp.rs index cbbcb53..0140734 100644 --- a/src/cpc_control/cpc_temp.rs +++ b/src/cpc_control/cpc_temp.rs @@ -1,6 +1,7 @@ use crate::constant::*; use crate::helper::cpc_type::{CPCTemp, CPCError}; use crate::device::tmp1075; +use crate::i2c_bus_lock::with_i2c_bus_lock; impl CPCTemp { pub fn new() -> Self { @@ -16,14 +17,16 @@ impl CPCTemp { } } pub fn read_temp() -> Result { - let cpc_tmp1075 = tmp1075::TMP1075::new(CPC_I2C_BUS, CPC_TMP1075_ADDRESS); - cpc_tmp1075.config()?; - let cpc_temp = cpc_tmp1075.read()?; + with_i2c_bus_lock(|| { + let cpc_tmp1075 = tmp1075::TMP1075::new(CPC_I2C_BUS, CPC_TMP1075_ADDRESS); + cpc_tmp1075.config()?; + let cpc_temp = cpc_tmp1075.read()?; - Ok( - CPCTemp { - cpc_temp, - } - ) + Ok( + CPCTemp { + cpc_temp, + } + ) + }) } } \ No newline at end of file diff --git a/src/cpc_control/cpc_vcp.rs b/src/cpc_control/cpc_vcp.rs index 1ba48bd..6d04b38 100644 --- a/src/cpc_control/cpc_vcp.rs +++ b/src/cpc_control/cpc_vcp.rs @@ -1,6 +1,7 @@ use crate::constant::*; use crate::helper::cpc_type::{CPCVcp, CPCError}; use crate::device::ina219; +use crate::i2c_bus_lock::with_i2c_bus_lock; impl CPCVcp { pub fn new() -> Self { @@ -16,19 +17,21 @@ impl CPCVcp { } } pub fn read_vcp() -> Result { - let cpc_ina219 = ina219::INA219::new( - CPC_I2C_BUS, - CPC_INA219_ADDRESS, - CPC_INA219_RSHUNT, - CPC_INA219_MEC, - ); - cpc_ina219.configure()?; - let cpc_vcp = cpc_ina219.read()?; + with_i2c_bus_lock(|| { + let cpc_ina219 = ina219::INA219::new( + CPC_I2C_BUS, + CPC_INA219_ADDRESS, + CPC_INA219_RSHUNT, + CPC_INA219_MEC, + ); + cpc_ina219.configure()?; + let cpc_vcp = cpc_ina219.read()?; - Ok( - CPCVcp{ - cpc_vcp, - } - ) + Ok( + CPCVcp{ + cpc_vcp, + } + ) + }) } } \ No newline at end of file diff --git a/src/helper/cpc_type.rs b/src/helper/cpc_type.rs index 43975e3..c9a5c3f 100644 --- a/src/helper/cpc_type.rs +++ b/src/helper/cpc_type.rs @@ -12,10 +12,18 @@ pub struct CPCVcp { pub enum CPCError { /// I2C Error I2C(i2cdev::linux::LinuxI2CError), + // IO Error + IO(std::io::Error), } impl From for CPCError { fn from(e: i2cdev::linux::LinuxI2CError) -> Self { CPCError::I2C(e) } +} + +impl From for CPCError { + fn from(e: std::io::Error) -> Self { + CPCError::IO(e) + } } \ No newline at end of file diff --git a/src/helper/ltb_type.rs b/src/helper/ltb_type.rs index dfdea29..248e49c 100644 --- a/src/helper/ltb_type.rs +++ b/src/helper/ltb_type.rs @@ -28,6 +28,8 @@ pub enum LTBError { I2C(i2cdev::linux::LinuxI2CError), // Setting Threshold Error SetThreshold, + // IO Error + IO(std::io::Error), } impl std::fmt::Display for LTBError { @@ -40,4 +42,10 @@ impl From for LTBError { fn from(e: i2cdev::linux::LinuxI2CError) -> Self { LTBError::I2C(e) } +} + +impl From for LTBError { + fn from(e: std::io::Error) -> Self { + LTBError::IO(e) + } } \ No newline at end of file diff --git a/src/helper/pa_type.rs b/src/helper/pa_type.rs index 598754a..2aa21b0 100644 --- a/src/helper/pa_type.rs +++ b/src/helper/pa_type.rs @@ -30,6 +30,8 @@ pub enum PAError { I2C(i2cdev::linux::LinuxI2CError), // PB Error PBError(crate::helper::pb_type::PBError), + // IO Error + IO(std::io::Error), } impl std::fmt::Display for PAError { @@ -48,4 +50,10 @@ impl From for PAError { fn from(e: crate::helper::pb_type::PBError) -> Self { PAError::PBError(e) } +} + +impl From for PAError { + fn from(e: std::io::Error) -> Self { + PAError::IO(e) + } } \ No newline at end of file diff --git a/src/helper/pb_type.rs b/src/helper/pb_type.rs index 77f051b..1d34c2e 100644 --- a/src/helper/pb_type.rs +++ b/src/helper/pb_type.rs @@ -31,6 +31,8 @@ pub struct PBVcp { pub enum PBError { // I2C Error I2C(i2cdev::linux::LinuxI2CError), + // IO Error + IO(std::io::Error), } impl std::fmt::Display for PBError { @@ -43,4 +45,10 @@ impl From for PBError { fn from(e: i2cdev::linux::LinuxI2CError) -> Self { PBError::I2C(e) } +} + +impl From for PBError { + fn from(e: std::io::Error) -> Self { + PBError::IO(e) + } } \ No newline at end of file diff --git a/src/helper/rb_type.rs b/src/helper/rb_type.rs index 5000969..dab2f4a 100644 --- a/src/helper/rb_type.rs +++ b/src/helper/rb_type.rs @@ -85,7 +85,9 @@ pub enum RBError { // OsString Error OsString, // Invalid Input Mode Error - InvalidInputMode + InvalidInputMode, + // IO Error + IO(std::io::Error), } impl std::fmt::Display for RBError { @@ -122,4 +124,10 @@ impl From for RBError { fn from(_: std::ffi::OsString) -> Self { RBError::OsString } +} + +impl From for RBError { + fn from(e: std::io::Error) -> Self { + RBError::IO(e) + } } \ No newline at end of file diff --git a/src/helper/tcpc_type.rs b/src/helper/tcpc_type.rs index f923337..8e400f6 100644 --- a/src/helper/tcpc_type.rs +++ b/src/helper/tcpc_type.rs @@ -8,26 +8,21 @@ pub struct TCPCVcp { pub tcpc_vcp: [f32; 3], } -#[derive(Debug)] -pub enum TCPCTempError { +pub enum TCPCError { /// I2C Error I2C(i2cdev::linux::LinuxI2CError), + // IO Error + IO(std::io::Error), } -impl From for TCPCTempError { +impl From for TCPCError { fn from(e: i2cdev::linux::LinuxI2CError) -> Self { - TCPCTempError::I2C(e) + TCPCError::I2C(e) } } -#[derive(Debug)] -pub enum TCPCVcpError { - /// I2C Error - I2C(i2cdev::linux::LinuxI2CError), -} - -impl From for TCPCVcpError { - fn from(e: i2cdev::linux::LinuxI2CError) -> Self { - TCPCVcpError::I2C(e) +impl From for TCPCError { + fn from(e: std::io::Error) -> Self { + TCPCError::IO(e) } } \ No newline at end of file diff --git a/src/i2c_bus_lock.rs b/src/i2c_bus_lock.rs new file mode 100644 index 0000000..0c8ec19 --- /dev/null +++ b/src/i2c_bus_lock.rs @@ -0,0 +1,34 @@ +use std::fs::OpenOptions; +use std::io; +use std::path::Path; +use once_cell::sync::Lazy; + +use crate::constant::I2C_BUS; + +static I2C_LOCK_PATH: Lazy = Lazy::new(|| { + format!("/var/lock/i2c-{}.lock", I2C_BUS) +}); + +pub fn with_i2c_bus_lock(f: F) -> Result +where + F: FnOnce() -> Result, + E: From, +{ + let lock_file = OpenOptions::new() + .read(true) + .write(true) + .create(true) + .open(Path::new(&*I2C_LOCK_PATH))?; + + lock_file.lock()?; + + let result = f(); + + let unlock_res = lock_file.unlock(); + + match (result, unlock_res) { + (Ok(val), Ok(())) => Ok(val), + (Ok(_), Err(e)) => Err(E::from(e)), + (Err(e), _) => Err(e), + } +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index d53d22b..8399100 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,6 +12,7 @@ pub mod tcpc_control; pub mod switch_control; pub mod mtb_control; pub mod tui; +pub mod i2c_bus_lock; // RATMoniData use serde_json; diff --git a/src/ltb_control/ltb_temp.rs b/src/ltb_control/ltb_temp.rs index ef21a86..a2ee520 100644 --- a/src/ltb_control/ltb_temp.rs +++ b/src/ltb_control/ltb_temp.rs @@ -4,6 +4,7 @@ use i2cdev::linux::LinuxI2CDevice; use crate::constant::*; use crate::helper::ltb_type::{LTBTemp, LTBError}; use crate::device::tmp112; +use crate::i2c_bus_lock::with_i2c_bus_lock; impl LTBTemp { pub fn new() -> Self { @@ -31,26 +32,32 @@ impl LTBTemp { ) } pub fn board_temp() -> Result { - let board_tmp112 = tmp112::TMP112::new(I2C_BUS, LTB_TMP112_ADDRESS); - board_tmp112.config()?; - let board_temp = board_tmp112.read()?; + with_i2c_bus_lock(|| { + let board_tmp112 = tmp112::TMP112::new(I2C_BUS, LTB_TMP112_ADDRESS); + board_tmp112.config()?; + let board_temp = board_tmp112.read()?; - Ok(board_temp) + Ok(board_temp) + }) } pub fn trenz_temp() -> Result { - let mut dev = LinuxI2CDevice::new(&format!("/dev/i2c-{}", I2C_BUS), LTB_TRENZ_ADDRESS)?; - let trenz_temp_raw = dev.smbus_read_i2c_block_data(LTB_TRENZ_TEMP_OFFSET as u8, 2)?; - let trenz_temp_adc = - (((trenz_temp_raw[0] as u16) << 4) | ((trenz_temp_raw[1] as u16) >> 4)) & 0xFFF; - let trenz_temp = (((trenz_temp_adc & 4095) as f32 * 503.975) / 4096.0) - 273.15; + with_i2c_bus_lock(|| { + let mut dev = LinuxI2CDevice::new(&format!("/dev/i2c-{}", I2C_BUS), LTB_TRENZ_ADDRESS)?; + let trenz_temp_raw = dev.smbus_read_i2c_block_data(LTB_TRENZ_TEMP_OFFSET as u8, 2)?; + let trenz_temp_adc = + (((trenz_temp_raw[0] as u16) << 4) | ((trenz_temp_raw[1] as u16) >> 4)) & 0xFFF; + let trenz_temp = (((trenz_temp_adc & 4095) as f32 * 503.975) / 4096.0) - 273.15; - Ok(trenz_temp) + Ok(trenz_temp) + }) } } pub fn config_temp() -> Result<(), LTBError> { - let ltb_tmp112 = tmp112::TMP112::new(I2C_BUS, LTB_TMP112_ADDRESS); - ltb_tmp112.config()?; + with_i2c_bus_lock(|| { + let ltb_tmp112 = tmp112::TMP112::new(I2C_BUS, LTB_TMP112_ADDRESS); + ltb_tmp112.config()?; - Ok(()) + Ok(()) + }) } \ No newline at end of file diff --git a/src/ltb_control/ltb_threshold.rs b/src/ltb_control/ltb_threshold.rs index 8bb2be0..efaa316 100644 --- a/src/ltb_control/ltb_threshold.rs +++ b/src/ltb_control/ltb_threshold.rs @@ -1,6 +1,7 @@ use crate::constant::*; use crate::helper::ltb_type::{LTBThreshold, LTBError}; use crate::device::max5815; +use crate::i2c_bus_lock::with_i2c_bus_lock; impl LTBThreshold { pub fn new() -> Self { @@ -19,27 +20,31 @@ impl LTBThreshold { } pub fn read_threshold(channel: u8) -> Result { - let ltb_dac = max5815::MAX5815::new(I2C_BUS, LTB_MAX5815_ADDRESS); - let threshold_raw = ltb_dac.read_dacn(channel)?; - let threshold = Self::adc_to_mv(threshold_raw); + with_i2c_bus_lock(|| { + let ltb_dac = max5815::MAX5815::new(I2C_BUS, LTB_MAX5815_ADDRESS); + let threshold_raw = ltb_dac.read_dacn(channel)?; + let threshold = Self::adc_to_mv(threshold_raw); - Ok(threshold) + Ok(threshold) + }) } pub fn read_thresholds() -> Result { - let ltb_dac: max5815::MAX5815 = max5815::MAX5815::new(I2C_BUS, LTB_MAX5815_ADDRESS); - let mut thresholds: [f32; 3] = Default::default(); - for i in 0..=2 { - let threshold_raw = ltb_dac.read_dacn(i)?; - thresholds[i as usize] = Self::adc_to_mv(threshold_raw); - } - - Ok( - LTBThreshold { - thresh_0: thresholds[0], - thresh_1: thresholds[1], - thresh_2: thresholds[2], + with_i2c_bus_lock(|| { + let ltb_dac: max5815::MAX5815 = max5815::MAX5815::new(I2C_BUS, LTB_MAX5815_ADDRESS); + let mut thresholds: [f32; 3] = Default::default(); + for i in 0..=2 { + let threshold_raw = ltb_dac.read_dacn(i)?; + thresholds[i as usize] = Self::adc_to_mv(threshold_raw); } - ) + + Ok( + LTBThreshold { + thresh_0: thresholds[0], + thresh_1: thresholds[1], + thresh_2: thresholds[2], + } + ) + }) } fn adc_to_mv(adc: u16) -> f32 { let voltage = LTB_DAC_REF_VOLTAGE * (adc as f32) / 2f32.powf(12.0); @@ -49,47 +54,51 @@ impl LTBThreshold { } pub fn set_default_threshold() -> Result<(), LTBError> { - let ltb_dac = max5815::MAX5815::new(I2C_BUS, LTB_MAX5815_ADDRESS); - ltb_dac.configure()?; + with_i2c_bus_lock(|| { + let ltb_dac = max5815::MAX5815::new(I2C_BUS, LTB_MAX5815_ADDRESS); + ltb_dac.configure()?; - let default_thresholds = [LTB_DAC_THRESHOLD_0, LTB_DAC_THRESHOLD_1, LTB_DAC_THRESHOLD_2]; + let default_thresholds = [LTB_DAC_THRESHOLD_0, LTB_DAC_THRESHOLD_1, LTB_DAC_THRESHOLD_2]; - for (i, default_threshold) in default_thresholds.iter().enumerate() { - ltb_dac.coden_loadn(i as u8, mv_to_adc(*default_threshold))?; - }; + for (i, default_threshold) in default_thresholds.iter().enumerate() { + ltb_dac.coden_loadn(i as u8, mv_to_adc(*default_threshold))?; + }; - Ok(()) + Ok(()) + }) } pub fn set_threshold(channel: u8, threshold: f32) -> Result<(), LTBError> { + with_i2c_bus_lock(|| { + if !(0..=2).contains(&channel) { + return Err(LTBError::SetThreshold) + } - if !(0..=2).contains(&channel) { - return Err(LTBError::SetThreshold) - } - - let ltb_dac = max5815::MAX5815::new(I2C_BUS, LTB_MAX5815_ADDRESS); - ltb_dac.configure()?; + let ltb_dac = max5815::MAX5815::new(I2C_BUS, LTB_MAX5815_ADDRESS); + ltb_dac.configure()?; - ltb_dac.coden_loadn(channel, mv_to_adc(threshold))?; + ltb_dac.coden_loadn(channel, mv_to_adc(threshold))?; - Ok(()) + Ok(()) + }) } pub fn set_thresholds(thresholds: [f32; 3]) -> Result<(), LTBError> { + with_i2c_bus_lock(|| { + let ltb_dac = max5815::MAX5815::new(I2C_BUS, LTB_MAX5815_ADDRESS); + ltb_dac.configure()?; - let ltb_dac = max5815::MAX5815::new(I2C_BUS, LTB_MAX5815_ADDRESS); - ltb_dac.configure()?; - - for (i, threshold) in thresholds.iter().enumerate() { + for (i, threshold) in thresholds.iter().enumerate() { - if (*threshold < 0.0) | (*threshold > 1000.0) { - return Err(LTBError::SetThreshold) + if (*threshold < 0.0) | (*threshold > 1000.0) { + return Err(LTBError::SetThreshold) + } + + ltb_dac.coden_loadn(i as u8, mv_to_adc(*threshold))?; } - - ltb_dac.coden_loadn(i as u8, mv_to_adc(*threshold))?; - } - Ok(()) + Ok(()) + }) } fn mv_to_adc(mv: f32) -> u16 { @@ -99,8 +108,10 @@ adc as u16 } pub fn reset_threshold() -> Result<(), LTBError> { - let ltb_dac = max5815::MAX5815::new(I2C_BUS, LTB_MAX5815_ADDRESS); - ltb_dac.reset_dac()?; + with_i2c_bus_lock(|| { + let ltb_dac = max5815::MAX5815::new(I2C_BUS, LTB_MAX5815_ADDRESS); + ltb_dac.reset_dac()?; - Ok(()) + Ok(()) + }) } \ No newline at end of file diff --git a/src/pa_control/pa_bias.rs b/src/pa_control/pa_bias.rs index edb9d98..a4dcf9f 100644 --- a/src/pa_control/pa_bias.rs +++ b/src/pa_control/pa_bias.rs @@ -2,6 +2,7 @@ use crate::constant::*; use crate::helper::pa_type::{PAReadBias, PASetBias, PATemp, PAError}; use crate::device::{max11615, max11617, max5825, pca9548a}; use crate::pb_control::pb_temp::read_pds_temp; +use crate::i2c_bus_lock::with_i2c_bus_lock; impl PAReadBias { pub fn new() -> Self { @@ -17,52 +18,54 @@ impl PAReadBias { } } pub fn read_bias() -> Result { - let mut read_biases: [f32; 16] = Default::default(); + with_i2c_bus_lock(|| { + let mut read_biases: [f32; 16] = Default::default(); - let preamp_channels = [ - PA_SEN_1_CHANNEL, PA_SEN_2_CHANNEL, PA_SEN_3_CHANNEL, PA_SEN_4_CHANNEL, - PA_SEN_5_CHANNEL, PA_SEN_6_CHANNEL, PA_SEN_7_CHANNEL, PA_SEN_8_CHANNEL, - PA_SEN_9_CHANNEL, PA_SEN_10_CHANNEL, PA_SEN_11_CHANNEL, PA_SEN_12_CHANNEL, - PA_SEN_13_CHANNEL, PA_SEN_14_CHANNEL, PA_SEN_15_CHANNEL, PA_SEN_16_CHANNEL, - ]; - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); - i2c_mux.select(PB_ADC_1_CHANNEL)?; - let max11615 = max11615::MAX11615::new(I2C_BUS, PB_MAX11615_ADDRESS); - max11615.setup()?; - let max11617 = max11617::MAX11617::new(I2C_BUS, PB_MAX11617_ADDRESS); - max11617.setup()?; + let preamp_channels = [ + PA_SEN_1_CHANNEL, PA_SEN_2_CHANNEL, PA_SEN_3_CHANNEL, PA_SEN_4_CHANNEL, + PA_SEN_5_CHANNEL, PA_SEN_6_CHANNEL, PA_SEN_7_CHANNEL, PA_SEN_8_CHANNEL, + PA_SEN_9_CHANNEL, PA_SEN_10_CHANNEL, PA_SEN_11_CHANNEL, PA_SEN_12_CHANNEL, + PA_SEN_13_CHANNEL, PA_SEN_14_CHANNEL, PA_SEN_15_CHANNEL, PA_SEN_16_CHANNEL, + ]; + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); + i2c_mux.select(PB_ADC_1_CHANNEL)?; + let max11615 = max11615::MAX11615::new(I2C_BUS, PB_MAX11615_ADDRESS); + max11615.setup()?; + let max11617 = max11617::MAX11617::new(I2C_BUS, PB_MAX11617_ADDRESS); + max11617.setup()?; - for i in 0..=7 { - if (0..=3).contains(&i) { - let preamp_bias_raw = max11615.read(preamp_channels[i])?; - read_biases[i] = Self::convert_bias_voltage(preamp_bias_raw); - } else { - let preamp_bias_raw = max11617.read(preamp_channels[i])?; - read_biases[i] = Self::convert_bias_voltage(preamp_bias_raw); + for i in 0..=7 { + if (0..=3).contains(&i) { + let preamp_bias_raw = max11615.read(preamp_channels[i])?; + read_biases[i] = Self::convert_bias_voltage(preamp_bias_raw); + } else { + let preamp_bias_raw = max11617.read(preamp_channels[i])?; + read_biases[i] = Self::convert_bias_voltage(preamp_bias_raw); + } } - } - i2c_mux.select(PB_ADC_2_CHANNEL)?; - max11615.setup()?; - max11617.setup()?; + i2c_mux.select(PB_ADC_2_CHANNEL)?; + max11615.setup()?; + max11617.setup()?; - for i in 8..=15 { - if (8..=11).contains(&i) { - let preamp_bias_raw = max11615.read(preamp_channels[i])?; - read_biases[i] = Self::convert_bias_voltage(preamp_bias_raw); - } else { - let preamp_bias_raw = max11617.read(preamp_channels[i])?; - read_biases[i] = Self::convert_bias_voltage(preamp_bias_raw); + for i in 8..=15 { + if (8..=11).contains(&i) { + let preamp_bias_raw = max11615.read(preamp_channels[i])?; + read_biases[i] = Self::convert_bias_voltage(preamp_bias_raw); + } else { + let preamp_bias_raw = max11617.read(preamp_channels[i])?; + read_biases[i] = Self::convert_bias_voltage(preamp_bias_raw); + } } - } - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok( - PAReadBias { - read_biases, - } - ) + Ok( + PAReadBias { + read_biases, + } + ) + }) } fn convert_bias_voltage(voltage: f32) -> f32 { // let bias_voltage = voltage * 22.27659574468085; @@ -74,236 +77,238 @@ impl PAReadBias { impl PASetBias { pub fn read_set_bias() -> Result { - - let preamp_bias_channels = [ - PA_DAC_1_CHANNEL, PA_DAC_2_CHANNEL, PA_DAC_3_CHANNEL, PA_DAC_4_CHANNEL, - PA_DAC_5_CHANNEL, PA_DAC_6_CHANNEL, PA_DAC_7_CHANNEL, PA_DAC_8_CHANNEL, - PA_DAC_9_CHANNEL, PA_DAC_10_CHANNEL, PA_DAC_11_CHANNEL, PA_DAC_12_CHANNEL, - PA_DAC_13_CHANNEL, PA_DAC_14_CHANNEL, PA_DAC_15_CHANNEL, PA_DAC_16_CHANNEL, - ]; - - let mut set_biases: [f32; 16] = Default::default(); - - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); - - i2c_mux.select(PB_DAC_1_CHANNEL)?; - let pb_dac_1 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS); - for i in 0..=7 { - set_biases[i] = Self::adc_to_bias(pb_dac_1.read_dacn(preamp_bias_channels[i])?); - } - - i2c_mux.select(PB_DAC_2_CHANNEL)?; - let pb_dac_2 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS); - for i in 8..=15 { - set_biases[i] = Self::adc_to_bias(pb_dac_2.read_dacn(preamp_bias_channels[i])?); - } - - i2c_mux.reset()?; - - Ok( - Self { - set_biases + with_i2c_bus_lock(|| { + let preamp_bias_channels = [ + PA_DAC_1_CHANNEL, PA_DAC_2_CHANNEL, PA_DAC_3_CHANNEL, PA_DAC_4_CHANNEL, + PA_DAC_5_CHANNEL, PA_DAC_6_CHANNEL, PA_DAC_7_CHANNEL, PA_DAC_8_CHANNEL, + PA_DAC_9_CHANNEL, PA_DAC_10_CHANNEL, PA_DAC_11_CHANNEL, PA_DAC_12_CHANNEL, + PA_DAC_13_CHANNEL, PA_DAC_14_CHANNEL, PA_DAC_15_CHANNEL, PA_DAC_16_CHANNEL, + ]; + + let mut set_biases: [f32; 16] = Default::default(); + + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); + + i2c_mux.select(PB_DAC_1_CHANNEL)?; + let pb_dac_1 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS); + for i in 0..=7 { + set_biases[i] = Self::adc_to_bias(pb_dac_1.read_dacn(preamp_bias_channels[i])?); + } + + i2c_mux.select(PB_DAC_2_CHANNEL)?; + let pb_dac_2 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS); + for i in 8..=15 { + set_biases[i] = Self::adc_to_bias(pb_dac_2.read_dacn(preamp_bias_channels[i])?); } - ) + + i2c_mux.reset()?; + + Ok( + Self { + set_biases + } + ) + }) } pub fn set_default_bias() -> Result<(), PAError> { - - let bias_voltage = Self::bias_to_adc(PA_DEFAULT_BIAS); - - let preamp_bias_channels = [ - PA_DAC_1_CHANNEL, PA_DAC_2_CHANNEL, PA_DAC_3_CHANNEL, PA_DAC_4_CHANNEL, - PA_DAC_5_CHANNEL, PA_DAC_6_CHANNEL, PA_DAC_7_CHANNEL, PA_DAC_8_CHANNEL, - PA_DAC_9_CHANNEL, PA_DAC_10_CHANNEL, PA_DAC_11_CHANNEL, PA_DAC_12_CHANNEL, - PA_DAC_13_CHANNEL, PA_DAC_14_CHANNEL, PA_DAC_15_CHANNEL, PA_DAC_16_CHANNEL, - ]; - - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); + with_i2c_bus_lock(|| { + let bias_voltage = Self::bias_to_adc(PA_DEFAULT_BIAS); - i2c_mux.select(PB_DAC_1_CHANNEL)?; - let pb_dac_1 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS); - for i in 0..=7 { - pb_dac_1.coden_loadn(preamp_bias_channels[i], bias_voltage)?; - } - - i2c_mux.select(PB_DAC_2_CHANNEL)?; - let pb_dac_2 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS); - for i in 8..=15 { - pb_dac_2.coden_loadn(preamp_bias_channels[i], bias_voltage)?; - } - - i2c_mux.reset()?; - - Ok(()) - + let preamp_bias_channels = [ + PA_DAC_1_CHANNEL, PA_DAC_2_CHANNEL, PA_DAC_3_CHANNEL, PA_DAC_4_CHANNEL, + PA_DAC_5_CHANNEL, PA_DAC_6_CHANNEL, PA_DAC_7_CHANNEL, PA_DAC_8_CHANNEL, + PA_DAC_9_CHANNEL, PA_DAC_10_CHANNEL, PA_DAC_11_CHANNEL, PA_DAC_12_CHANNEL, + PA_DAC_13_CHANNEL, PA_DAC_14_CHANNEL, PA_DAC_15_CHANNEL, PA_DAC_16_CHANNEL, + ]; + + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); + + i2c_mux.select(PB_DAC_1_CHANNEL)?; + let pb_dac_1 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS); + for i in 0..=7 { + pb_dac_1.coden_loadn(preamp_bias_channels[i], bias_voltage)?; + } + + i2c_mux.select(PB_DAC_2_CHANNEL)?; + let pb_dac_2 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS); + for i in 8..=15 { + pb_dac_2.coden_loadn(preamp_bias_channels[i], bias_voltage)?; + } + + i2c_mux.reset()?; + + Ok(()) + }) } pub fn set_manual_bias(channel: Option, bias: f32) -> Result<(), PAError> { - - if bias < 0.0 || bias > 67.0 { - eprintln!("Bias voltage must be between 0V to 67V"); - std::process::exit(1); - } - - let bias_voltage = Self::bias_to_adc(bias); - - let preamp_bias_channels = [ - PA_DAC_1_CHANNEL, PA_DAC_2_CHANNEL, PA_DAC_3_CHANNEL, PA_DAC_4_CHANNEL, - PA_DAC_5_CHANNEL, PA_DAC_6_CHANNEL, PA_DAC_7_CHANNEL, PA_DAC_8_CHANNEL, - PA_DAC_9_CHANNEL, PA_DAC_10_CHANNEL, PA_DAC_11_CHANNEL, PA_DAC_12_CHANNEL, - PA_DAC_13_CHANNEL, PA_DAC_14_CHANNEL, PA_DAC_15_CHANNEL, PA_DAC_16_CHANNEL, - ]; - - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); - match channel { - None => { - i2c_mux.select(PB_DAC_1_CHANNEL)?; - let pb_dac_1 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS); - for i in 0..=7 { - pb_dac_1.coden_loadn(preamp_bias_channels[i], bias_voltage)?; - } - - i2c_mux.select(PB_DAC_2_CHANNEL)?; - let pb_dac_2 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS); - for i in 8..=15 { - pb_dac_2.coden_loadn(preamp_bias_channels[i], bias_voltage)?; - } + with_i2c_bus_lock(|| { + if bias < 0.0 || bias > 67.0 { + eprintln!("Bias voltage must be between 0V to 67V"); + std::process::exit(1); } - Some(mut ch) => { - if ch < 1 || ch > 16 { - eprintln!("Channel must be between 1 to 16."); - std::process::exit(1); - } + let bias_voltage = Self::bias_to_adc(bias); - ch = ch - 1; + let preamp_bias_channels = [ + PA_DAC_1_CHANNEL, PA_DAC_2_CHANNEL, PA_DAC_3_CHANNEL, PA_DAC_4_CHANNEL, + PA_DAC_5_CHANNEL, PA_DAC_6_CHANNEL, PA_DAC_7_CHANNEL, PA_DAC_8_CHANNEL, + PA_DAC_9_CHANNEL, PA_DAC_10_CHANNEL, PA_DAC_11_CHANNEL, PA_DAC_12_CHANNEL, + PA_DAC_13_CHANNEL, PA_DAC_14_CHANNEL, PA_DAC_15_CHANNEL, PA_DAC_16_CHANNEL, + ]; - if (0..=7).contains(&ch) { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); + match channel { + None => { i2c_mux.select(PB_DAC_1_CHANNEL)?; let pb_dac_1 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS); - pb_dac_1.coden_loadn(preamp_bias_channels[ch as usize], bias_voltage)?; - } else { + for i in 0..=7 { + pb_dac_1.coden_loadn(preamp_bias_channels[i], bias_voltage)?; + } + i2c_mux.select(PB_DAC_2_CHANNEL)?; let pb_dac_2 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS); - pb_dac_2.coden_loadn(preamp_bias_channels[ch as usize], bias_voltage)? + for i in 8..=15 { + pb_dac_2.coden_loadn(preamp_bias_channels[i], bias_voltage)?; + } + } + Some(mut ch) => { + + if ch < 1 || ch > 16 { + eprintln!("Channel must be between 1 to 16."); + std::process::exit(1); + } + + ch = ch - 1; + + if (0..=7).contains(&ch) { + i2c_mux.select(PB_DAC_1_CHANNEL)?; + let pb_dac_1 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS); + pb_dac_1.coden_loadn(preamp_bias_channels[ch as usize], bias_voltage)?; + } else { + i2c_mux.select(PB_DAC_2_CHANNEL)?; + let pb_dac_2 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS); + pb_dac_2.coden_loadn(preamp_bias_channels[ch as usize], bias_voltage)? + } } } - } - - i2c_mux.reset()?; - - Ok(()) + + i2c_mux.reset()?; + + Ok(()) + }) } pub fn set_manual_biases(biases: [f32; 16]) -> Result<(), PAError> { - - for bias in biases { - if bias < 0.0 || bias > 67.0 { - eprintln!("Bias voltage must be between 0V to 67V"); - std::process::exit(1); + with_i2c_bus_lock(|| { + for bias in biases { + if bias < 0.0 || bias > 67.0 { + eprintln!("Bias voltage must be between 0V to 67V"); + std::process::exit(1); + } } - } - let preamp_bias_channels = [ - PA_DAC_1_CHANNEL, PA_DAC_2_CHANNEL, PA_DAC_3_CHANNEL, PA_DAC_4_CHANNEL, - PA_DAC_5_CHANNEL, PA_DAC_6_CHANNEL, PA_DAC_7_CHANNEL, PA_DAC_8_CHANNEL, - PA_DAC_9_CHANNEL, PA_DAC_10_CHANNEL, PA_DAC_11_CHANNEL, PA_DAC_12_CHANNEL, - PA_DAC_13_CHANNEL, PA_DAC_14_CHANNEL, PA_DAC_15_CHANNEL, PA_DAC_16_CHANNEL, - ]; + let preamp_bias_channels = [ + PA_DAC_1_CHANNEL, PA_DAC_2_CHANNEL, PA_DAC_3_CHANNEL, PA_DAC_4_CHANNEL, + PA_DAC_5_CHANNEL, PA_DAC_6_CHANNEL, PA_DAC_7_CHANNEL, PA_DAC_8_CHANNEL, + PA_DAC_9_CHANNEL, PA_DAC_10_CHANNEL, PA_DAC_11_CHANNEL, PA_DAC_12_CHANNEL, + PA_DAC_13_CHANNEL, PA_DAC_14_CHANNEL, PA_DAC_15_CHANNEL, PA_DAC_16_CHANNEL, + ]; - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); - i2c_mux.select(PB_DAC_1_CHANNEL)?; - let pb_dac_1 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS); - for i in 0..=7 { - pb_dac_1.coden_loadn(preamp_bias_channels[i], Self::bias_to_adc(biases[i]))?; - } - - i2c_mux.select(PB_DAC_2_CHANNEL)?; - let pb_dac_2 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS); - for i in 8..=15 { - pb_dac_2.coden_loadn(preamp_bias_channels[i], Self::bias_to_adc(biases[i]))?; - } - - i2c_mux.reset()?; + i2c_mux.select(PB_DAC_1_CHANNEL)?; + let pb_dac_1 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS); + for i in 0..=7 { + pb_dac_1.coden_loadn(preamp_bias_channels[i], Self::bias_to_adc(biases[i]))?; + } + + i2c_mux.select(PB_DAC_2_CHANNEL)?; + let pb_dac_2 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS); + for i in 8..=15 { + pb_dac_2.coden_loadn(preamp_bias_channels[i], Self::bias_to_adc(biases[i]))?; + } + + i2c_mux.reset()?; - Ok(()) + Ok(()) + }) } pub fn set_bias() -> Result<(), PAError> { + with_i2c_bus_lock(|| { + let preamp_bias_channels = [ + PA_DAC_1_CHANNEL, PA_DAC_2_CHANNEL, PA_DAC_3_CHANNEL, PA_DAC_4_CHANNEL, + PA_DAC_5_CHANNEL, PA_DAC_6_CHANNEL, PA_DAC_7_CHANNEL, PA_DAC_8_CHANNEL, + PA_DAC_9_CHANNEL, PA_DAC_10_CHANNEL, PA_DAC_11_CHANNEL, PA_DAC_12_CHANNEL, + PA_DAC_13_CHANNEL, PA_DAC_14_CHANNEL, PA_DAC_15_CHANNEL, PA_DAC_16_CHANNEL, + ]; + + let mut bias_voltages: [u16; 16] = Default::default(); - // let mut bias_voltage = Default::default(); - - let preamp_bias_channels = [ - PA_DAC_1_CHANNEL, PA_DAC_2_CHANNEL, PA_DAC_3_CHANNEL, PA_DAC_4_CHANNEL, - PA_DAC_5_CHANNEL, PA_DAC_6_CHANNEL, PA_DAC_7_CHANNEL, PA_DAC_8_CHANNEL, - PA_DAC_9_CHANNEL, PA_DAC_10_CHANNEL, PA_DAC_11_CHANNEL, PA_DAC_12_CHANNEL, - PA_DAC_13_CHANNEL, PA_DAC_14_CHANNEL, PA_DAC_15_CHANNEL, PA_DAC_16_CHANNEL, - ]; - - let mut bias_voltages: [u16; 16] = Default::default(); - - let read_biases = PAReadBias::read_bias()?.read_biases; - let set_biases = Self::read_set_bias()?.set_biases; - - for i in 0..=15 { - if set_biases[i] == 0.0 { - let bias_stc = Self::sipm_temp_comp(i)?; - let bias_ptc = Self::pb_temp_comp(bias_stc)?; + let read_biases = PAReadBias::read_bias()?.read_biases; + let set_biases = Self::read_set_bias()?.set_biases; + + for i in 0..=15 { + if set_biases[i] == 0.0 { + let bias_stc = Self::sipm_temp_comp(i)?; + let bias_ptc = Self::pb_temp_comp(bias_stc)?; - bias_voltages[i] = Self::bias_to_adc(bias_ptc); - // if [0, 3, 7, 8, 11, 14].contains(&i) { - // println!("Preamp {} Case 1: {}", i+1, bias_ptc); - // } - } else { - let delta = (read_biases[i] - set_biases[i]).abs(); - if delta > 0.1 { - if read_biases[i] > set_biases[i] { - bias_voltages[i] = Self::bias_to_adc(set_biases[i] + delta); - // if [0, 3, 7, 8, 11, 14].contains(&i) { - // println!("Preamp {} Case 2: {}", i+1, set_biases[i] + delta); - // } - } else if read_biases[i] < set_biases[i] { - bias_voltages[i] = Self::bias_to_adc(set_biases[i] - delta); - // if [0, 3, 7, 8, 11, 14].contains(&i) { - // println!("Preamp {} Case 3: {}", i+1, set_biases[i] + delta); - // } + bias_voltages[i] = Self::bias_to_adc(bias_ptc); + // if [0, 3, 7, 8, 11, 14].contains(&i) { + // println!("Preamp {} Case 1: {}", i+1, bias_ptc); + // } + } else { + let delta = (read_biases[i] - set_biases[i]).abs(); + if delta > 0.1 { + if read_biases[i] > set_biases[i] { + bias_voltages[i] = Self::bias_to_adc(set_biases[i] + delta); + // if [0, 3, 7, 8, 11, 14].contains(&i) { + // println!("Preamp {} Case 2: {}", i+1, set_biases[i] + delta); + // } + } else if read_biases[i] < set_biases[i] { + bias_voltages[i] = Self::bias_to_adc(set_biases[i] - delta); + // if [0, 3, 7, 8, 11, 14].contains(&i) { + // println!("Preamp {} Case 3: {}", i+1, set_biases[i] + delta); + // } + } else { + bias_voltages[i] = Self::bias_to_adc(set_biases[i]); + // if [0, 3, 7, 8, 11, 14].contains(&i) { + // println!("Preamp {} Case 4: {}", i+1, set_biases[i]); + // } + } } else { - bias_voltages[i] = Self::bias_to_adc(set_biases[i]); + let bias_stc = Self::sipm_temp_comp(i)?; + let bias_ptc = Self::pb_temp_comp(bias_stc)?; + + bias_voltages[i] = Self::bias_to_adc(bias_ptc); // if [0, 3, 7, 8, 11, 14].contains(&i) { - // println!("Preamp {} Case 4: {}", i+1, set_biases[i]); + // println!("Preamp {} Case 5: {}", i+1, bias_ptc); // } } - } else { - let bias_stc = Self::sipm_temp_comp(i)?; - let bias_ptc = Self::pb_temp_comp(bias_stc)?; - - bias_voltages[i] = Self::bias_to_adc(bias_ptc); - // if [0, 3, 7, 8, 11, 14].contains(&i) { - // println!("Preamp {} Case 5: {}", i+1, bias_ptc); - // } } } - } - - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); - i2c_mux.select(PB_DAC_1_CHANNEL)?; - let pb_dac_1 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS); - for i in 0..=7 { - pb_dac_1.coden_loadn(preamp_bias_channels[i], bias_voltages[i])?; - } - - i2c_mux.select(PB_DAC_2_CHANNEL)?; - let pb_dac_2 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS); - for i in 8..=15 { - pb_dac_2.coden_loadn(preamp_bias_channels[i], bias_voltages[i])?; - } - - i2c_mux.reset()?; - - Ok(()) + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); + + i2c_mux.select(PB_DAC_1_CHANNEL)?; + let pb_dac_1 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS); + for i in 0..=7 { + pb_dac_1.coden_loadn(preamp_bias_channels[i], bias_voltages[i])?; + } + + i2c_mux.select(PB_DAC_2_CHANNEL)?; + let pb_dac_2 = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS); + for i in 8..=15 { + pb_dac_2.coden_loadn(preamp_bias_channels[i], bias_voltages[i])?; + } + + i2c_mux.reset()?; + + Ok(()) + }) } pub fn sipm_temp_comp(ch: usize) -> Result { let bias_voltage; - let preamp_temp = PATemp::read_signle_temp(ch)?; + let preamp_temp = PATemp::read_single_temp(ch)?; if preamp_temp == f32::MAX { bias_voltage = 0.0 } else { @@ -329,18 +334,19 @@ impl PASetBias { Ok(bias_voltage) } pub fn reset_bias() -> Result<(), PAError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); - - i2c_mux.select(PB_DAC_1_CHANNEL)?; - let pb_dac = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS); - pb_dac.reset_dac()?; - i2c_mux.select(PB_DAC_2_CHANNEL)?; - pb_dac.reset_dac()?; - - i2c_mux.reset()?; - - Ok(()) - + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); + + i2c_mux.select(PB_DAC_1_CHANNEL)?; + let pb_dac = max5825::MAX5825::new(I2C_BUS, PB_MAX5825_ADDRESS); + pb_dac.reset_dac()?; + i2c_mux.select(PB_DAC_2_CHANNEL)?; + pb_dac.reset_dac()?; + + i2c_mux.reset()?; + + Ok(()) + }) } fn bias_to_adc(bias_voltage: f32) -> u16 { let adc = (bias_voltage / 22.3) / PB_DAC_REF_VOLTAGE * 2f32.powi(12); diff --git a/src/pa_control/pa_temp.rs b/src/pa_control/pa_temp.rs index a6b6d4d..79bdd50 100644 --- a/src/pa_control/pa_temp.rs +++ b/src/pa_control/pa_temp.rs @@ -1,6 +1,7 @@ use crate::constant::*; use crate::helper::pa_type::{PATemp, PAError}; use crate::device::{max11615, max11617, pca9548a}; +use crate::i2c_bus_lock::with_i2c_bus_lock; impl PATemp { pub fn new() -> Self { @@ -17,104 +18,105 @@ impl PATemp { } pub fn read_temp() -> Result { - let mut pa_temps: [f32; 16] = Default::default(); + with_i2c_bus_lock(|| { + let mut pa_temps: [f32; 16] = Default::default(); - let pa_channels = [ - PA_TEMP_1_CHNANNEL, PA_TEMP_2_CHNANNEL, PA_TEMP_3_CHNANNEL, PA_TEMP_4_CHNANNEL, - PA_TEMP_5_CHNANNEL, PA_TEMP_6_CHNANNEL, PA_TEMP_7_CHNANNEL, PA_TEMP_8_CHNANNEL, - PA_TEMP_9_CHNANNEL, PA_TEMP_10_CHNANNEL, PA_TEMP_11_CHNANNEL, PA_TEMP_12_CHNANNEL, - PA_TEMP_13_CHNANNEL, PA_TEMP_14_CHNANNEL, PA_TEMP_15_CHNANNEL, PA_TEMP_16_CHNANNEL, - ]; - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); - i2c_mux.select(PB_ADC_1_CHANNEL)?; - let max11615 = max11615::MAX11615::new(I2C_BUS, PB_MAX11615_ADDRESS); - max11615.setup()?; - let max11617 = max11617::MAX11617::new(I2C_BUS, PB_MAX11617_ADDRESS); - max11617.setup()?; + let pa_channels = [ + PA_TEMP_1_CHNANNEL, PA_TEMP_2_CHNANNEL, PA_TEMP_3_CHNANNEL, PA_TEMP_4_CHNANNEL, + PA_TEMP_5_CHNANNEL, PA_TEMP_6_CHNANNEL, PA_TEMP_7_CHNANNEL, PA_TEMP_8_CHNANNEL, + PA_TEMP_9_CHNANNEL, PA_TEMP_10_CHNANNEL, PA_TEMP_11_CHNANNEL, PA_TEMP_12_CHNANNEL, + PA_TEMP_13_CHNANNEL, PA_TEMP_14_CHNANNEL, PA_TEMP_15_CHNANNEL, PA_TEMP_16_CHNANNEL, + ]; + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); + i2c_mux.select(PB_ADC_1_CHANNEL)?; + let max11615 = max11615::MAX11615::new(I2C_BUS, PB_MAX11615_ADDRESS); + max11615.setup()?; + let max11617 = max11617::MAX11617::new(I2C_BUS, PB_MAX11617_ADDRESS); + max11617.setup()?; - for i in 0..=7 { - if (0..=3).contains(&i) { - let preamp_temp_raw = max11615.read(pa_channels[i])?; - pa_temps[i] = Self::voltage_to_temp(preamp_temp_raw); - } else { - let preamp_temp_raw = max11617.read(pa_channels[i])?; - pa_temps[i] = Self::voltage_to_temp(preamp_temp_raw); - } - } - - i2c_mux.select(PB_ADC_2_CHANNEL)?; - max11615.setup()?; - max11617.setup()?; - - for i in 8..=15 { - if (8..=11).contains(&i) { - let preamp_temp_raw = max11615.read(pa_channels[i])?; - pa_temps[i] = Self::voltage_to_temp(preamp_temp_raw); - } else { - let preamp_temp_raw = max11617.read(pa_channels[i])?; - pa_temps[i] = Self::voltage_to_temp(preamp_temp_raw); + for i in 0..=7 { + if (0..=3).contains(&i) { + let preamp_temp_raw = max11615.read(pa_channels[i])?; + pa_temps[i] = Self::voltage_to_temp(preamp_temp_raw); + } else { + let preamp_temp_raw = max11617.read(pa_channels[i])?; + pa_temps[i] = Self::voltage_to_temp(preamp_temp_raw); + } } - } - i2c_mux.reset()?; + i2c_mux.select(PB_ADC_2_CHANNEL)?; + max11615.setup()?; + max11617.setup()?; - Ok( - PATemp { - pa_temps + for i in 8..=15 { + if (8..=11).contains(&i) { + let preamp_temp_raw = max11615.read(pa_channels[i])?; + pa_temps[i] = Self::voltage_to_temp(preamp_temp_raw); + } else { + let preamp_temp_raw = max11617.read(pa_channels[i])?; + pa_temps[i] = Self::voltage_to_temp(preamp_temp_raw); + } } - ) + i2c_mux.reset()?; + Ok( + PATemp { + pa_temps + } + ) + }) } - pub fn read_signle_temp(ch: usize) -> Result { - let pa_temp; + pub fn read_single_temp(ch: usize) -> Result { + with_i2c_bus_lock(|| { + let pa_temp; - let pa_channels = [ - PA_TEMP_1_CHNANNEL, PA_TEMP_2_CHNANNEL, PA_TEMP_3_CHNANNEL, PA_TEMP_4_CHNANNEL, - PA_TEMP_5_CHNANNEL, PA_TEMP_6_CHNANNEL, PA_TEMP_7_CHNANNEL, PA_TEMP_8_CHNANNEL, - PA_TEMP_9_CHNANNEL, PA_TEMP_10_CHNANNEL, PA_TEMP_11_CHNANNEL, PA_TEMP_12_CHNANNEL, - PA_TEMP_13_CHNANNEL, PA_TEMP_14_CHNANNEL, PA_TEMP_15_CHNANNEL, PA_TEMP_16_CHNANNEL, - ]; + let pa_channels = [ + PA_TEMP_1_CHNANNEL, PA_TEMP_2_CHNANNEL, PA_TEMP_3_CHNANNEL, PA_TEMP_4_CHNANNEL, + PA_TEMP_5_CHNANNEL, PA_TEMP_6_CHNANNEL, PA_TEMP_7_CHNANNEL, PA_TEMP_8_CHNANNEL, + PA_TEMP_9_CHNANNEL, PA_TEMP_10_CHNANNEL, PA_TEMP_11_CHNANNEL, PA_TEMP_12_CHNANNEL, + PA_TEMP_13_CHNANNEL, PA_TEMP_14_CHNANNEL, PA_TEMP_15_CHNANNEL, PA_TEMP_16_CHNANNEL, + ]; - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); - let max11615 = max11615::MAX11615::new(I2C_BUS, PB_MAX11615_ADDRESS); - let max11617 = max11617::MAX11617::new(I2C_BUS, PB_MAX11617_ADDRESS); - - match ch { - 0..=3 => { - i2c_mux.select(PB_ADC_1_CHANNEL)?; - max11615.setup()?; - let pa_temp_raw = max11615.read(pa_channels[ch])?; - pa_temp = Self::voltage_to_temp(pa_temp_raw); - } - 4..=7 => { - i2c_mux.select(PB_ADC_1_CHANNEL)?; - max11617.setup()?; - let pa_temp_raw = max11617.read(pa_channels[ch])?; - pa_temp = Self::voltage_to_temp(pa_temp_raw); - } - 8..=11 => { - i2c_mux.select(PB_ADC_2_CHANNEL)?; - max11615.setup()?; - let pa_temp_raw = max11615.read(pa_channels[ch])?; - pa_temp = Self::voltage_to_temp(pa_temp_raw); - } - 12..=15 => { - i2c_mux.select(PB_ADC_2_CHANNEL)?; - max11617.setup()?; - let pa_temp_raw = max11617.read(pa_channels[ch])?; - pa_temp = Self::voltage_to_temp(pa_temp_raw); - } - _ => { - pa_temp = f32::MAX; + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); + let max11615 = max11615::MAX11615::new(I2C_BUS, PB_MAX11615_ADDRESS); + let max11617 = max11617::MAX11617::new(I2C_BUS, PB_MAX11617_ADDRESS); + + match ch { + 0..=3 => { + i2c_mux.select(PB_ADC_1_CHANNEL)?; + max11615.setup()?; + let pa_temp_raw = max11615.read(pa_channels[ch])?; + pa_temp = Self::voltage_to_temp(pa_temp_raw); + } + 4..=7 => { + i2c_mux.select(PB_ADC_1_CHANNEL)?; + max11617.setup()?; + let pa_temp_raw = max11617.read(pa_channels[ch])?; + pa_temp = Self::voltage_to_temp(pa_temp_raw); + } + 8..=11 => { + i2c_mux.select(PB_ADC_2_CHANNEL)?; + max11615.setup()?; + let pa_temp_raw = max11615.read(pa_channels[ch])?; + pa_temp = Self::voltage_to_temp(pa_temp_raw); + } + 12..=15 => { + i2c_mux.select(PB_ADC_2_CHANNEL)?; + max11617.setup()?; + let pa_temp_raw = max11617.read(pa_channels[ch])?; + pa_temp = Self::voltage_to_temp(pa_temp_raw); + } + _ => { + pa_temp = f32::MAX; + } } - } - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok(pa_temp) + Ok(pa_temp) + }) } - fn voltage_to_temp(voltage: f32) -> f32 { let mut temperature = (voltage - 0.5) * 100.0; if -60.0 > temperature || temperature > 150.0 { diff --git a/src/pb_control/pb_ltb_pwr.rs b/src/pb_control/pb_ltb_pwr.rs index 3c6f528..e4ceded 100644 --- a/src/pb_control/pb_ltb_pwr.rs +++ b/src/pb_control/pb_ltb_pwr.rs @@ -1,19 +1,22 @@ use crate::constant::*; use crate::helper::pb_type::PBError; use crate::device::{max7320, pca9548a}; +use crate::i2c_bus_lock::with_i2c_bus_lock; pub fn ltb_pwr_switch(switch: bool) -> Result<(), PBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); - i2c_mux.select(PB_MAX7320_CHANNEL)?; + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); + i2c_mux.select(PB_MAX7320_CHANNEL)?; - let ltb_pwr = max7320::MAX7320::new(I2C_BUS, PB_MAX7320_ADDRESS); - if switch { - ltb_pwr.output_on_0_3()?; - } else { - ltb_pwr.output_off_all()?; - } + let ltb_pwr = max7320::MAX7320::new(I2C_BUS, PB_MAX7320_ADDRESS); + if switch { + ltb_pwr.output_on_0_3()?; + } else { + ltb_pwr.output_off_all()?; + } - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok(()) + Ok(()) + }) } \ No newline at end of file diff --git a/src/pb_control/pb_temp.rs b/src/pb_control/pb_temp.rs index 59ac8a8..41f826a 100644 --- a/src/pb_control/pb_temp.rs +++ b/src/pb_control/pb_temp.rs @@ -1,6 +1,7 @@ use crate::constant::*; use crate::helper::pb_type::{PBTemp, PBError}; use crate::device::{pca9548a, tmp1075}; +use crate::i2c_bus_lock::with_i2c_bus_lock; impl PBTemp { pub fn new() -> Self { @@ -20,73 +21,78 @@ impl PBTemp { } pub fn read_temp() -> Result { + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); + i2c_mux.select(PB_TMP1075_CHANNEL)?; + + // Positive Degital Supply DC-DC Converter Temperature + let pds_tmp1075 = tmp1075::TMP1075::new(I2C_BUS, PB_PDS_TMP1075_ADDRESS); + pds_tmp1075.config()?; + let pds_temp = pds_tmp1075.read()?; + + // Positive Analog Supply DC-DC Converter Temperature + let pas_tmp1075 = tmp1075::TMP1075::new(I2C_BUS, PB_PAS_TMP1075_ADDRESS); + pas_tmp1075.config()?; + let pas_temp = pas_tmp1075.read()?; + + // Negative Analog Supply DC-DC Converter Temperature + let nas_tmp1075 = tmp1075::TMP1075::new(I2C_BUS, PB_NAS_TMP1075_ADDRESS); + nas_tmp1075.config()?; + let nas_temp = nas_tmp1075.read()?; + + // SiPM High Voltage Supply DC-DC Converter Temperature + let shv_tmp1075 = tmp1075::TMP1075::new(I2C_BUS, PB_SHV_TMP1075_ADDRESS); + shv_tmp1075.config()?; + let shv_temp = shv_tmp1075.read()?; + + i2c_mux.reset()?; + + Ok( + PBTemp { + pds_temp, + pas_temp, + nas_temp, + shv_temp, + } + ) + }) + } +} + +pub fn config_temp() -> Result<(), PBError> { + with_i2c_bus_lock(|| { let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); i2c_mux.select(PB_TMP1075_CHANNEL)?; - // Positive Degital Supply DC-DC Converter Temperature let pds_tmp1075 = tmp1075::TMP1075::new(I2C_BUS, PB_PDS_TMP1075_ADDRESS); pds_tmp1075.config()?; - let pds_temp = pds_tmp1075.read()?; - // Positive Analog Supply DC-DC Converter Temperature let pas_tmp1075 = tmp1075::TMP1075::new(I2C_BUS, PB_PAS_TMP1075_ADDRESS); pas_tmp1075.config()?; - let pas_temp = pas_tmp1075.read()?; - // Negative Analog Supply DC-DC Converter Temperature let nas_tmp1075 = tmp1075::TMP1075::new(I2C_BUS, PB_NAS_TMP1075_ADDRESS); nas_tmp1075.config()?; - let nas_temp = nas_tmp1075.read()?; - // SiPM High Voltage Supply DC-DC Converter Temperature let shv_tmp1075 = tmp1075::TMP1075::new(I2C_BUS, PB_SHV_TMP1075_ADDRESS); shv_tmp1075.config()?; - let shv_temp = shv_tmp1075.read()?; i2c_mux.reset()?; - Ok( - PBTemp { - pds_temp, - pas_temp, - nas_temp, - shv_temp, - } - ) - - } -} - -pub fn config_temp() -> Result<(), PBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); - i2c_mux.select(PB_TMP1075_CHANNEL)?; - - let pds_tmp1075 = tmp1075::TMP1075::new(I2C_BUS, PB_PDS_TMP1075_ADDRESS); - pds_tmp1075.config()?; - - let pas_tmp1075 = tmp1075::TMP1075::new(I2C_BUS, PB_PAS_TMP1075_ADDRESS); - pas_tmp1075.config()?; - - let nas_tmp1075 = tmp1075::TMP1075::new(I2C_BUS, PB_NAS_TMP1075_ADDRESS); - nas_tmp1075.config()?; - - let shv_tmp1075 = tmp1075::TMP1075::new(I2C_BUS, PB_SHV_TMP1075_ADDRESS); - shv_tmp1075.config()?; - - i2c_mux.reset()?; - - Ok(()) + Ok(()) + }) } pub fn read_pds_temp() -> Result { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); - i2c_mux.select(PB_TMP1075_CHANNEL)?; + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); + i2c_mux.select(PB_TMP1075_CHANNEL)?; - let pds_tmp1075 = tmp1075::TMP1075::new(I2C_BUS, PB_PDS_TMP1075_ADDRESS); - pds_tmp1075.config()?; - let pds_temp = pds_tmp1075.read()?; + let pds_tmp1075 = tmp1075::TMP1075::new(I2C_BUS, PB_PDS_TMP1075_ADDRESS); + pds_tmp1075.config()?; + let pds_temp = pds_tmp1075.read()?; - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok(pds_temp) + Ok(pds_temp) + }) } \ No newline at end of file diff --git a/src/pb_control/pb_vcp.rs b/src/pb_control/pb_vcp.rs index 9633ce3..05d1caf 100644 --- a/src/pb_control/pb_vcp.rs +++ b/src/pb_control/pb_vcp.rs @@ -1,6 +1,7 @@ use crate::constant::*; use crate::helper::pb_type::{PBVcp, PBError}; use crate::device::{ina219, ina226, max11617, pca9548a}; +use crate::i2c_bus_lock::with_i2c_bus_lock; impl PBVcp { pub fn new() -> Self { @@ -21,8 +22,83 @@ impl PBVcp { } } pub fn read_vcp() -> Result { + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); + + i2c_mux.select(PB_P3V6_PA_INA226_CHANNEL)?; + let p3v6_pa_ina226 = ina226::INA226::new( + I2C_BUS, + PB_P3V6_PA_INA226_ADDRESS, + PB_P3V6_PA_INA226_RSHUNT, + PB_P3V6_PA_INA226_MEC, + ); + p3v6_pa_ina226.configure()?; + let p3v6_pa_vcp = p3v6_pa_ina226.read()?; + + i2c_mux.select(PB_ADC_1_CHANNEL)?; + let max11617 = max11617::MAX11617::new(I2C_BUS, PB_MAX11617_ADDRESS); + max11617.setup()?; + let n1v6_pa_voltage = max11617.read(PB_N1V6_PA_VOLTAGE_INA201_CHANNEL)? * -1.0; + let n1v6_pa_current = max11617.read(PB_N1V6_PA_CURRENT_INA201_CHANNEL)? / 50.0 / 0.1; + let n1v6_pa_power = n1v6_pa_voltage.abs() * n1v6_pa_current; + let n1v6_pa_vcp = [n1v6_pa_voltage, n1v6_pa_current, n1v6_pa_power]; + + i2c_mux.select(PB_LTB_INA219_CHANNEL)?; + let p3v4f_ltb_ina219 = ina219::INA219::new( + I2C_BUS, + PB_P3V4F_LTB_INA219_ADDRESS, + PB_P3V4F_LTB_INA219_RSHUNT, + PB_P3V4F_LTB_INA219_MEC, + ); + p3v4f_ltb_ina219.configure()?; + let p3v4f_ltb_vcp = p3v4f_ltb_ina219.read()?; + + let p3v4d_ltb_ina219 = ina219::INA219::new( + I2C_BUS, + PB_P3V4D_LTB_INA219_ADDRESS, + PB_P3V4D_LTB_INA219_RSHUNT, + PB_P3V4D_LTB_INA219_MEC, + ); + p3v4d_ltb_ina219.configure()?; + let p3v4d_ltb_vcp = p3v4d_ltb_ina219.read()?; + + let p3v6_ltb_ina219 = ina219::INA219::new( + I2C_BUS, + PB_P3V6_LTB_INA219_ADDRESS, + PB_P3V6_LTB_INA219_RSHUNT, + PB_P3V6_LTB_INA219_MEC, + ); + p3v6_ltb_ina219.configure()?; + let p3v6_ltb_vcp = p3v6_ltb_ina219.read()?; + + i2c_mux.select(PB_ADC_2_CHANNEL)?; + let max11617 = max11617::MAX11617::new(I2C_BUS, PB_MAX11617_ADDRESS); + max11617.setup()?; + let n1v6_ltb_voltage = max11617.read(PB_N1V6_LTB_VOLTAGE_INA202_CHANNEL)? * -1.0; + let n1v6_ltb_current = max11617.read(PB_N1V6_LTB_CURRENT_INA202_CHANNEL)? / 100.0 / 0.1; + let n1v6_ltb_power = n1v6_ltb_voltage.abs() * n1v6_ltb_current; + let n1v6_ltb_vcp = [n1v6_ltb_voltage, n1v6_ltb_current, n1v6_ltb_power]; + + i2c_mux.reset()?; + + Ok( + PBVcp { + p3v6_pa_vcp, + n1v6_pa_vcp, + p3v4f_ltb_vcp, + p3v4d_ltb_vcp, + p3v6_ltb_vcp, + n1v6_ltb_vcp, + } + ) + }) + } +} + +pub fn config_vcp() -> Result<(), PBError> { + with_i2c_bus_lock(|| { let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); - + i2c_mux.select(PB_P3V6_PA_INA226_CHANNEL)?; let p3v6_pa_ina226 = ina226::INA226::new( I2C_BUS, @@ -30,16 +106,14 @@ impl PBVcp { PB_P3V6_PA_INA226_RSHUNT, PB_P3V6_PA_INA226_MEC, ); - p3v6_pa_ina226.configure()?; - let p3v6_pa_vcp = p3v6_pa_ina226.read()?; + for _ in 0..3 { + p3v6_pa_ina226.configure()?; + p3v6_pa_ina226.read()?; + } i2c_mux.select(PB_ADC_1_CHANNEL)?; let max11617 = max11617::MAX11617::new(I2C_BUS, PB_MAX11617_ADDRESS); max11617.setup()?; - let n1v6_pa_voltage = max11617.read(PB_N1V6_PA_VOLTAGE_INA201_CHANNEL)? * -1.0; - let n1v6_pa_current = max11617.read(PB_N1V6_PA_CURRENT_INA201_CHANNEL)? / 50.0 / 0.1; - let n1v6_pa_power = n1v6_pa_voltage.abs() * n1v6_pa_current; - let n1v6_pa_vcp = [n1v6_pa_voltage, n1v6_pa_current, n1v6_pa_power]; i2c_mux.select(PB_LTB_INA219_CHANNEL)?; let p3v4f_ltb_ina219 = ina219::INA219::new( @@ -48,8 +122,10 @@ impl PBVcp { PB_P3V4F_LTB_INA219_RSHUNT, PB_P3V4F_LTB_INA219_MEC, ); - p3v4f_ltb_ina219.configure()?; - let p3v4f_ltb_vcp = p3v4f_ltb_ina219.read()?; + for _ in 0..3 { + p3v4f_ltb_ina219.configure()?; + p3v4f_ltb_ina219.read()?; + } let p3v4d_ltb_ina219 = ina219::INA219::new( I2C_BUS, @@ -57,8 +133,10 @@ impl PBVcp { PB_P3V4D_LTB_INA219_RSHUNT, PB_P3V4D_LTB_INA219_MEC, ); - p3v4d_ltb_ina219.configure()?; - let p3v4d_ltb_vcp = p3v4d_ltb_ina219.read()?; + for _ in 0..3 { + p3v4d_ltb_ina219.configure()?; + p3v4d_ltb_ina219.read()?; + } let p3v6_ltb_ina219 = ina219::INA219::new( I2C_BUS, @@ -66,90 +144,17 @@ impl PBVcp { PB_P3V6_LTB_INA219_RSHUNT, PB_P3V6_LTB_INA219_MEC, ); - p3v6_ltb_ina219.configure()?; - let p3v6_ltb_vcp = p3v6_ltb_ina219.read()?; + for _ in 0..3 { + p3v6_ltb_ina219.configure()?; + p3v6_ltb_ina219.read()?; + } i2c_mux.select(PB_ADC_2_CHANNEL)?; let max11617 = max11617::MAX11617::new(I2C_BUS, PB_MAX11617_ADDRESS); max11617.setup()?; - let n1v6_ltb_voltage = max11617.read(PB_N1V6_LTB_VOLTAGE_INA202_CHANNEL)? * -1.0; - let n1v6_ltb_current = max11617.read(PB_N1V6_LTB_CURRENT_INA202_CHANNEL)? / 100.0 / 0.1; - let n1v6_ltb_power = n1v6_ltb_voltage.abs() * n1v6_ltb_current; - let n1v6_ltb_vcp = [n1v6_ltb_voltage, n1v6_ltb_current, n1v6_ltb_power]; i2c_mux.reset()?; - Ok( - PBVcp { - p3v6_pa_vcp, - n1v6_pa_vcp, - p3v4f_ltb_vcp, - p3v4d_ltb_vcp, - p3v6_ltb_vcp, - n1v6_ltb_vcp, - } - ) - } -} - -pub fn config_vcp() -> Result<(), PBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, PB_PCA9548A_ADDRESS); - - i2c_mux.select(PB_P3V6_PA_INA226_CHANNEL)?; - let p3v6_pa_ina226 = ina226::INA226::new( - I2C_BUS, - PB_P3V6_PA_INA226_ADDRESS, - PB_P3V6_PA_INA226_RSHUNT, - PB_P3V6_PA_INA226_MEC, - ); - for _ in 0..3 { - p3v6_pa_ina226.configure()?; - p3v6_pa_ina226.read()?; - } - - i2c_mux.select(PB_ADC_1_CHANNEL)?; - let max11617 = max11617::MAX11617::new(I2C_BUS, PB_MAX11617_ADDRESS); - max11617.setup()?; - - i2c_mux.select(PB_LTB_INA219_CHANNEL)?; - let p3v4f_ltb_ina219 = ina219::INA219::new( - I2C_BUS, - PB_P3V4F_LTB_INA219_ADDRESS, - PB_P3V4F_LTB_INA219_RSHUNT, - PB_P3V4F_LTB_INA219_MEC, - ); - for _ in 0..3 { - p3v4f_ltb_ina219.configure()?; - p3v4f_ltb_ina219.read()?; - } - - let p3v4d_ltb_ina219 = ina219::INA219::new( - I2C_BUS, - PB_P3V4D_LTB_INA219_ADDRESS, - PB_P3V4D_LTB_INA219_RSHUNT, - PB_P3V4D_LTB_INA219_MEC, - ); - for _ in 0..3 { - p3v4d_ltb_ina219.configure()?; - p3v4d_ltb_ina219.read()?; - } - - let p3v6_ltb_ina219 = ina219::INA219::new( - I2C_BUS, - PB_P3V6_LTB_INA219_ADDRESS, - PB_P3V6_LTB_INA219_RSHUNT, - PB_P3V6_LTB_INA219_MEC, - ); - for _ in 0..3 { - p3v6_ltb_ina219.configure()?; - p3v6_ltb_ina219.read()?; - } - - i2c_mux.select(PB_ADC_2_CHANNEL)?; - let max11617 = max11617::MAX11617::new(I2C_BUS, PB_MAX11617_ADDRESS); - max11617.setup()?; - - i2c_mux.reset()?; - - Ok(()) + Ok(()) + }) } \ No newline at end of file diff --git a/src/rb_control/rb_clk.rs b/src/rb_control/rb_clk.rs index 44770c1..17e3847 100644 --- a/src/rb_control/rb_clk.rs +++ b/src/rb_control/rb_clk.rs @@ -2,87 +2,94 @@ use crate::constant::*; use crate::device::{pca9548a, si5345b}; use crate::helper::rb_type::RBError; +use crate::i2c_bus_lock::with_i2c_bus_lock; pub fn configure_clk_synth() -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_SI5345B_CHANNEL)?; + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_SI5345B_CHANNEL)?; - let si5345b = si5345b::SI5345B::new(I2C_BUS, RB_SI5345B_ADDRESS); - si5345b.configure_si5345b()?; - - i2c_mux.reset()?; + let si5345b = si5345b::SI5345B::new(I2C_BUS, RB_SI5345B_ADDRESS); + si5345b.configure_si5345b()?; + + i2c_mux.reset()?; - Ok(()) + Ok(()) + }) } pub fn program_nvm_clk_synth(verbose: bool) -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_SI5345B_CHANNEL)?; - - let si5345b = si5345b::SI5345B::new(I2C_BUS, RB_SI5345B_ADDRESS); - - // Check how many user banks available - let available_nvm_bank = si5345b.read_available_nvm_bank()?; - match available_nvm_bank { - 2 => { - if verbose { - println!("Number of User Banks Available to Burn: 2"); + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_SI5345B_CHANNEL)?; + + let si5345b = si5345b::SI5345B::new(I2C_BUS, RB_SI5345B_ADDRESS); + + // Check how many user banks available + let available_nvm_bank = si5345b.read_available_nvm_bank()?; + match available_nvm_bank { + 2 => { + if verbose { + println!("Number of User Banks Available to Burn: 2"); + } + }, + 1 => { + if verbose { + println!("Number of User Banks Available to Burn: 1"); + } + } + 0 => { + println!("Number of User Banks Available to Burn: 0"); + println!("Exiting the program..."); + std::process::exit(1); } - }, - 1 => { - if verbose { - println!("Number of User Banks Available to Burn: 1"); + _ => { + println!("ACTIVE_NVM_BANK Error"); + println!("Exiting the program..."); + std::process::exit(1); } } - 0 => { - println!("Number of User Banks Available to Burn: 0"); - println!("Exiting the program..."); - std::process::exit(1); + + // Program SI5345B NVM + if verbose { + println!("Programming SI5345B NVM..."); + } + si5345b.configure_nvm_si5345b()?; + if verbose { + println!("Done programming SI5345B NVM"); } - _ => { - println!("ACTIVE_NVM_BANK Error"); - println!("Exiting the program..."); - std::process::exit(1); + + i2c_mux.reset()?; + + if verbose { + println!("Complete programming SI5345B NVM!"); } - } - - // Program SI5345B NVM - if verbose { - println!("Programming SI5345B NVM..."); - } - si5345b.configure_nvm_si5345b()?; - if verbose { - println!("Done programming SI5345B NVM"); - } - - i2c_mux.reset()?; - - if verbose { - println!("Complete programming SI5345B NVM!"); - } - - Ok(()) + + Ok(()) + }) } pub fn reset_clk_synth(rst_type: u8) -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_SI5345B_CHANNEL)?; + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_SI5345B_CHANNEL)?; - let si5345b = si5345b::SI5345B::new(I2C_BUS, RB_SI5345B_ADDRESS); + let si5345b = si5345b::SI5345B::new(I2C_BUS, RB_SI5345B_ADDRESS); - match rst_type { - 0 => { - si5345b.soft_reset_si5345b()?; - si5345b.configure_si5345b()?; - } - 1 => { - si5345b.hard_reset_si5345b()?; + match rst_type { + 0 => { + si5345b.soft_reset_si5345b()?; + si5345b.configure_si5345b()?; + } + 1 => { + si5345b.hard_reset_si5345b()?; + } + _ => {}, } - _ => {}, - } - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok(()) + Ok(()) + }) } diff --git a/src/rb_control/rb_config.rs b/src/rb_control/rb_config.rs index e9bc8ca..7129121 100644 --- a/src/rb_control/rb_config.rs +++ b/src/rb_control/rb_config.rs @@ -37,8 +37,6 @@ impl RBConfig { rb1_id_arr.push(*rb1_id); rb2_id_arr.push(*rb2_id); pb_id_arr.push(*pb_id); - - // println!("{}, {}, {}, {}, {}", rat_id, ltb_id, rb1_id, rb2_id, pb_id); } Self { @@ -50,39 +48,3 @@ impl RBConfig { } } } -// pub fn rb_config_read() { -// let rb_config_csv = include_str!("../config/nts_config.csv"); -// let mut reader = csv::ReaderBuilder::new() -// .comment(Some(b'#')) -// .escape(Some(b'\\')) -// .flexible(true) -// .from_reader(rb_config_csv.as_bytes()); - -// let mut rat_id_arr: Vec = Vec::new(); -// let mut ltb_id_arr: Vec = Vec::new(); -// let mut rb1_id_arr: Vec = Vec::new(); -// let mut rb2_id_arr: Vec = Vec::new(); -// let mut pb_id_arr: Vec = Vec::new(); - -// for (i, record) in reader.records().enumerate() { -// let record = record.expect("failed to convert record"); -// let rat_id = &record[0].parse::().unwrap(); -// let ltb_id = &record[1].parse::().unwrap(); -// let rb1_id = &record[2].parse::().unwrap(); -// let rb2_id = &record[3].parse::().unwrap(); -// let pb_id = &record[4].parse::().unwrap(); - -// rat_id_arr.push(*rat_id); -// ltb_id_arr.push(*ltb_id); -// rb1_id_arr.push(*rb1_id); -// rb2_id_arr.push(*rb2_id); -// pb_id_arr.push(*pb_id); - -// // println!("{}, {}, {}, {}, {}", rat_id, ltb_id, rb1_id, rb2_id, pb_id); -// } -// println!("{:?}", rat_id_arr); -// println!("{:?}", ltb_id_arr); -// println!("{:?}", rb1_id_arr); -// println!("{:?}", rb2_id_arr); -// println!("{:?}", pb_id_arr); -// } diff --git a/src/rb_control/rb_dac.rs b/src/rb_control/rb_dac.rs index e766888..08d67da 100644 --- a/src/rb_control/rb_dac.rs +++ b/src/rb_control/rb_dac.rs @@ -1,6 +1,7 @@ use crate::constant::*; use crate::helper::rb_type::{RBDac, RBError}; use crate::device::{ad5675, pca9548a}; +use crate::i2c_bus_lock::with_i2c_bus_lock; impl RBDac { pub fn new() -> Self { @@ -20,204 +21,227 @@ impl RBDac { } } pub fn read_dac() -> Result { + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_AD5675_CHANNEL)?; + let ad5675 = ad5675::AD5675::new(I2C_BUS, RB_AD5675_ADDRESS); + + let in_neg: f32 = ad5675.read_dac_voltage(0)?; + let in_pos: f32 = ad5675.read_dac_voltage(1)?; + let drs_rofs: f32 = ad5675.read_dac_voltage(2)?; + let v_cm: f32 = ad5675.read_dac_voltage(3)?; + let drs_bias: f32 = ad5675.read_dac_voltage(4)?; + + i2c_mux.reset()?; + + Ok( + RBDac { in_neg, in_pos, drs_rofs, v_cm, drs_bias } + ) + }) + } + +} + +pub fn set_dac() -> Result<(), RBError> { + with_i2c_bus_lock(|| { let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); i2c_mux.select(RB_AD5675_CHANNEL)?; let ad5675 = ad5675::AD5675::new(I2C_BUS, RB_AD5675_ADDRESS); - let in_neg: f32 = ad5675.read_dac_voltage(0)?; - let in_pos: f32 = ad5675.read_dac_voltage(1)?; - let drs_rofs: f32 = ad5675.read_dac_voltage(2)?; - let v_cm: f32 = ad5675.read_dac_voltage(3)?; - let drs_bias: f32 = ad5675.read_dac_voltage(4)?; + /* DAC settings + Next few lines will configure the DAC outputs for DRS4/analog front end + The AD5675 is a 16-bit DAC with range 0 to 2.048 V + Decimal step size is: 0.00003125 V / integer + + DAC Channels: + 0x0: Vout - + 0x1: Vout + + 0X2: ROFS + 0X3: THS4509 Common Voltage + 0X4: DRS BIAS + */ + + // DRS4 analog input offset/bias: IN+_OFS, IN-_OFS + // in_neg + ad5675.write_dac(0, RB_AD5675_DAC0)?; + // in_pos + ad5675.write_dac(1, RB_AD5675_DAC1)?; + // offset + // DRS ROFS 1V, 1.6V max + // ad5675.write_dac(2, 35200); + ad5675.write_dac(2, RB_AD5675_DAC2)?; + // THS4509 common mode voltage: V_CM + // For +3.5 V and -1.5 V split supply, half range is 1 V + ad5675.write_dac(3, RB_AD5675_DAC3)?; + // DRS BIAS 0.7V + ad5675.write_dac(4, RB_AD5675_DAC4)?; i2c_mux.reset()?; - Ok( - RBDac { in_neg, in_pos, drs_rofs, v_cm, drs_bias } - ) - } - -} - -pub fn set_dac() -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_AD5675_CHANNEL)?; - let ad5675 = ad5675::AD5675::new(I2C_BUS, RB_AD5675_ADDRESS); - - /* DAC settings - Next few lines will configure the DAC outputs for DRS4/analog front end - The AD5675 is a 16-bit DAC with range 0 to 2.048 V - Decimal step size is: 0.00003125 V / integer - - DAC Channels: - 0x0: Vout - - 0x1: Vout + - 0X2: ROFS - 0X3: THS4509 Common Voltage - 0X4: DRS BIAS - */ - - // DRS4 analog input offset/bias: IN+_OFS, IN-_OFS - // in_neg - ad5675.write_dac(0, RB_AD5675_DAC0)?; - // in_pos - ad5675.write_dac(1, RB_AD5675_DAC1)?; - // offset - // DRS ROFS 1V, 1.6V max - // ad5675.write_dac(2, 35200); - ad5675.write_dac(2, RB_AD5675_DAC2)?; - // THS4509 common mode voltage: V_CM - // For +3.5 V and -1.5 V split supply, half range is 1 V - ad5675.write_dac(3, RB_AD5675_DAC3)?; - // DRS BIAS 0.7V - ad5675.write_dac(4, RB_AD5675_DAC4)?; - - i2c_mux.reset()?; - - Ok(()) - + Ok(()) + }) } pub fn read_dac() -> Result<[u16; 5], RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_AD5675_CHANNEL)?; - let ad5675 = ad5675::AD5675::new(I2C_BUS, RB_AD5675_ADDRESS); - - let mut dac_values: [u16; 5] = [u16::max_value(); 5]; - for i in 0..=4 { - let dac = ad5675.read_dac(i)?; - dac_values[i as usize] = dac; - } + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_AD5675_CHANNEL)?; + let ad5675 = ad5675::AD5675::new(I2C_BUS, RB_AD5675_ADDRESS); - i2c_mux.reset()?; + let mut dac_values: [u16; 5] = [u16::max_value(); 5]; + for i in 0..=4 { + let dac = ad5675.read_dac(i)?; + dac_values[i as usize] = dac; + } + + i2c_mux.reset()?; - Ok(dac_values) + Ok(dac_values) + }) } pub fn read_single_dac(channel: u8) -> Result { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_AD5675_CHANNEL)?; - let ad5675 = ad5675::AD5675::new(I2C_BUS, RB_AD5675_ADDRESS); + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_AD5675_CHANNEL)?; + let ad5675 = ad5675::AD5675::new(I2C_BUS, RB_AD5675_ADDRESS); - let dac = ad5675.read_dac(channel)?; + let dac = ad5675.read_dac(channel)?; - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok(dac) + Ok(dac) + }) } pub fn zero_dac() -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_AD5675_CHANNEL)?; - let ad5675 = ad5675::AD5675::new(I2C_BUS, RB_AD5675_ADDRESS); + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_AD5675_CHANNEL)?; + let ad5675 = ad5675::AD5675::new(I2C_BUS, RB_AD5675_ADDRESS); - for i in 0..=4 { - ad5675.write_dac(i, 0)?; - } + for i in 0..=4 { + ad5675.write_dac(i, 0)?; + } - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok(()) + Ok(()) + }) } pub fn set_dac_500() -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_AD5675_CHANNEL)?; - let ad5675 = ad5675::AD5675::new(I2C_BUS, RB_AD5675_ADDRESS); + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_AD5675_CHANNEL)?; + let ad5675 = ad5675::AD5675::new(I2C_BUS, RB_AD5675_ADDRESS); - ad5675.write_dac(2, 49600)?; + ad5675.write_dac(2, 49600)?; - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok(()) + Ok(()) + }) } pub fn set_single_dac(channel: u8, value: u16) -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_AD5675_CHANNEL)?; - let ad5675 = ad5675::AD5675::new(I2C_BUS, RB_AD5675_ADDRESS); + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_AD5675_CHANNEL)?; + let ad5675 = ad5675::AD5675::new(I2C_BUS, RB_AD5675_ADDRESS); - ad5675.write_dac(channel, value)?; + ad5675.write_dac(channel, value)?; - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok(()) + Ok(()) + }) } pub fn set_input_range(lower_bound: f32) -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_AD5675_CHANNEL)?; - let ad5675 = ad5675::AD5675::new(I2C_BUS, RB_AD5675_ADDRESS); + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_AD5675_CHANNEL)?; + let ad5675 = ad5675::AD5675::new(I2C_BUS, RB_AD5675_ADDRESS); - let rofs: u16 = ((1.05 - (lower_bound / 1000.0)) * 32000.0) as u16; - println!("Setting ROFS to: {}", rofs); + let rofs: u16 = ((1.05 - (lower_bound / 1000.0)) * 32000.0) as u16; + println!("Setting ROFS to: {}", rofs); - ad5675.write_dac(2, rofs)?; - i2c_mux.reset()?; + ad5675.write_dac(2, rofs)?; + i2c_mux.reset()?; - Ok(()) + Ok(()) + }) } pub fn dac_noi_mode() -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_AD5675_CHANNEL)?; - let ad5675 = ad5675::AD5675::new(I2C_BUS, RB_AD5675_ADDRESS); + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_AD5675_CHANNEL)?; + let ad5675 = ad5675::AD5675::new(I2C_BUS, RB_AD5675_ADDRESS); - ad5675.write_dac(0, RB_AD5675_DAC0)?; - ad5675.write_dac(1, RB_AD5675_DAC1)?; - ad5675.write_dac(2, RB_AD5675_DAC2)?; - ad5675.write_dac(3, RB_AD5675_DAC3)?; - ad5675.write_dac(4, RB_AD5675_DAC4)?; + ad5675.write_dac(0, RB_AD5675_DAC0)?; + ad5675.write_dac(1, RB_AD5675_DAC1)?; + ad5675.write_dac(2, RB_AD5675_DAC2)?; + ad5675.write_dac(3, RB_AD5675_DAC3)?; + ad5675.write_dac(4, RB_AD5675_DAC4)?; - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok(()) + Ok(()) + }) } pub fn dac_vcal_mode() -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_AD5675_CHANNEL)?; - let ad5675 = ad5675::AD5675::new(I2C_BUS, RB_AD5675_ADDRESS); + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_AD5675_CHANNEL)?; + let ad5675 = ad5675::AD5675::new(I2C_BUS, RB_AD5675_ADDRESS); - ad5675.write_dac(0, RB_AD5675_DAC0)?; - ad5675.write_dac(1, RB_AD5675_DAC1_VCAL)?; - ad5675.write_dac(2, RB_AD5675_DAC2)?; - ad5675.write_dac(3, RB_AD5675_DAC3)?; - ad5675.write_dac(4, RB_AD5675_DAC4)?; + ad5675.write_dac(0, RB_AD5675_DAC0)?; + ad5675.write_dac(1, RB_AD5675_DAC1_VCAL)?; + ad5675.write_dac(2, RB_AD5675_DAC2)?; + ad5675.write_dac(3, RB_AD5675_DAC3)?; + ad5675.write_dac(4, RB_AD5675_DAC4)?; - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok(()) + Ok(()) + }) } pub fn dac_tcal_mode() -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_AD5675_CHANNEL)?; - let ad5675 = ad5675::AD5675::new(I2C_BUS, RB_AD5675_ADDRESS); + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_AD5675_CHANNEL)?; + let ad5675 = ad5675::AD5675::new(I2C_BUS, RB_AD5675_ADDRESS); - ad5675.write_dac(0, RB_AD5675_DAC0)?; - ad5675.write_dac(1, RB_AD5675_DAC1)?; - ad5675.write_dac(2, RB_AD5675_DAC2)?; - ad5675.write_dac(3, RB_AD5675_DAC3)?; - ad5675.write_dac(4, RB_AD5675_DAC4)?; + ad5675.write_dac(0, RB_AD5675_DAC0)?; + ad5675.write_dac(1, RB_AD5675_DAC1)?; + ad5675.write_dac(2, RB_AD5675_DAC2)?; + ad5675.write_dac(3, RB_AD5675_DAC3)?; + ad5675.write_dac(4, RB_AD5675_DAC4)?; - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok(()) + Ok(()) + }) } pub fn dac_sma_mode() -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_AD5675_CHANNEL)?; - let ad5675 = ad5675::AD5675::new(I2C_BUS, RB_AD5675_ADDRESS); + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_AD5675_CHANNEL)?; + let ad5675 = ad5675::AD5675::new(I2C_BUS, RB_AD5675_ADDRESS); - ad5675.write_dac(0, RB_AD5675_DAC0)?; - ad5675.write_dac(1, RB_AD5675_DAC1)?; - ad5675.write_dac(2, RB_AD5675_DAC2)?; - ad5675.write_dac(3, RB_AD5675_DAC3)?; - ad5675.write_dac(4, RB_AD5675_DAC4)?; + ad5675.write_dac(0, RB_AD5675_DAC0)?; + ad5675.write_dac(1, RB_AD5675_DAC1)?; + ad5675.write_dac(2, RB_AD5675_DAC2)?; + ad5675.write_dac(3, RB_AD5675_DAC3)?; + ad5675.write_dac(4, RB_AD5675_DAC4)?; - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok(()) + Ok(()) + }) } \ No newline at end of file diff --git a/src/rb_control/rb_gpioe.rs b/src/rb_control/rb_gpioe.rs index 2308698..6aa492b 100644 --- a/src/rb_control/rb_gpioe.rs +++ b/src/rb_control/rb_gpioe.rs @@ -5,6 +5,7 @@ use crate::constant::*; use crate::helper::rb_type::RBError; use crate::device::cy8c9560a::CY8C9560A; use crate::device::{cy8c9560a, pca9548a}; +use crate::i2c_bus_lock::with_i2c_bus_lock; /* Ports used for Readout Board V2.5.2 @@ -68,148 +69,160 @@ GP7: 0x3F */ pub fn initialize_gpioe() -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_CY8C9560A_CHANNEL)?; - - let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); - - // Port 0 - cy8c9560a.select_port(0)?; - cy8c9560a.set_interrupt_mask_port(0x00)?; - cy8c9560a.set_pin_direction(0x00)?; - cy8c9560a.set_drive_mode(4)?; - - // Port 1 - cy8c9560a.select_port(1)?; - cy8c9560a.set_interrupt_mask_port(0x00)?; - cy8c9560a.set_pin_direction(0x00)?; - cy8c9560a.set_drive_mode(1)?; - - // Port 2 - cy8c9560a.select_port(2)?; - cy8c9560a.set_interrupt_mask_port(0x00)?; - cy8c9560a.set_pin_direction(0x00)?; - cy8c9560a.set_drive_mode(4)?; - - // Port 3 - cy8c9560a.select_port(3)?; - cy8c9560a.set_interrupt_mask_port(0x00)?; - cy8c9560a.set_pin_direction(0x00)?; - cy8c9560a.set_drive_mode(4)?; - - // Port 4 - cy8c9560a.select_port(4)?; - cy8c9560a.set_interrupt_mask_port(0x00)?; - cy8c9560a.set_pin_direction(0x00)?; - cy8c9560a.set_drive_mode(4)?; - - // Port 5 - cy8c9560a.select_port(5)?; - cy8c9560a.set_interrupt_mask_port(0x00)?; - cy8c9560a.set_pin_direction(0x00)?; - cy8c9560a.set_drive_mode(4)?; - - // Port 6 - cy8c9560a.select_port(6)?; - cy8c9560a.set_interrupt_mask_port(0x00)?; - cy8c9560a.set_pin_direction(0x00)?; - cy8c9560a.set_drive_mode(1)?; - - // Port 7 - cy8c9560a.select_port(7)?; - cy8c9560a.set_interrupt_mask_port(0x00)?; - cy8c9560a.set_pin_direction(0x00)?; - cy8c9560a.set_drive_mode(4)?; - - // Set ouput ports - cy8c9560a.set_output_port(0, 0x00)?; - cy8c9560a.set_output_port(1, 0xFF)?; - cy8c9560a.set_output_port(2, 0x03)?; - cy8c9560a.set_output_port(3, 0x13)?; - cy8c9560a.set_output_port(4, 0xFC)?; - cy8c9560a.set_output_port(5, 0x33)?; - cy8c9560a.set_output_port(6, 0xFF)?; - cy8c9560a.set_output_port(7, 0x3F)?; - - i2c_mux.reset()?; - - Ok(()) + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_CY8C9560A_CHANNEL)?; + + let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); + + // Port 0 + cy8c9560a.select_port(0)?; + cy8c9560a.set_interrupt_mask_port(0x00)?; + cy8c9560a.set_pin_direction(0x00)?; + cy8c9560a.set_drive_mode(4)?; + + // Port 1 + cy8c9560a.select_port(1)?; + cy8c9560a.set_interrupt_mask_port(0x00)?; + cy8c9560a.set_pin_direction(0x00)?; + cy8c9560a.set_drive_mode(1)?; + + // Port 2 + cy8c9560a.select_port(2)?; + cy8c9560a.set_interrupt_mask_port(0x00)?; + cy8c9560a.set_pin_direction(0x00)?; + cy8c9560a.set_drive_mode(4)?; + + // Port 3 + cy8c9560a.select_port(3)?; + cy8c9560a.set_interrupt_mask_port(0x00)?; + cy8c9560a.set_pin_direction(0x00)?; + cy8c9560a.set_drive_mode(4)?; + + // Port 4 + cy8c9560a.select_port(4)?; + cy8c9560a.set_interrupt_mask_port(0x00)?; + cy8c9560a.set_pin_direction(0x00)?; + cy8c9560a.set_drive_mode(4)?; + + // Port 5 + cy8c9560a.select_port(5)?; + cy8c9560a.set_interrupt_mask_port(0x00)?; + cy8c9560a.set_pin_direction(0x00)?; + cy8c9560a.set_drive_mode(4)?; + + // Port 6 + cy8c9560a.select_port(6)?; + cy8c9560a.set_interrupt_mask_port(0x00)?; + cy8c9560a.set_pin_direction(0x00)?; + cy8c9560a.set_drive_mode(1)?; + + // Port 7 + cy8c9560a.select_port(7)?; + cy8c9560a.set_interrupt_mask_port(0x00)?; + cy8c9560a.set_pin_direction(0x00)?; + cy8c9560a.set_drive_mode(4)?; + + // Set ouput ports + cy8c9560a.set_output_port(0, 0x00)?; + cy8c9560a.set_output_port(1, 0xFF)?; + cy8c9560a.set_output_port(2, 0x03)?; + cy8c9560a.set_output_port(3, 0x13)?; + cy8c9560a.set_output_port(4, 0xFC)?; + cy8c9560a.set_output_port(5, 0x33)?; + cy8c9560a.set_output_port(6, 0xFF)?; + cy8c9560a.set_output_port(7, 0x3F)?; + + i2c_mux.reset()?; + + Ok(()) + }) } pub fn reset_si5345b_gpioe() -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_CY8C9560A_CHANNEL)?; + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_CY8C9560A_CHANNEL)?; - let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); - let mut value = cy8c9560a.read_port_status(3)?; - value = value ^ 0x01; - cy8c9560a.set_output_port(3, value)?; - value = cy8c9560a.read_port_status(3)?; - value = value | 0x01; - cy8c9560a.set_output_port(3, value)?; + let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); + let mut value = cy8c9560a.read_port_status(3)?; + value = value ^ 0x01; + cy8c9560a.set_output_port(3, value)?; + value = cy8c9560a.read_port_status(3)?; + value = value | 0x01; + cy8c9560a.set_output_port(3, value)?; - i2c_mux.reset()?; + i2c_mux.reset()?; - thread::sleep(Duration::from_millis(2000)); + thread::sleep(Duration::from_millis(2000)); - Ok(()) + Ok(()) + }) } pub fn enable_si5345b_gpioe() -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_CY8C9560A_CHANNEL)?; + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_CY8C9560A_CHANNEL)?; - let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); - let mut value = cy8c9560a.read_port_status(3)?; - value = (value & !0x02) | 0 << 1; - cy8c9560a.set_output_port(3, value)?; + let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); + let mut value = cy8c9560a.read_port_status(3)?; + value = (value & !0x02) | 0 << 1; + cy8c9560a.set_output_port(3, value)?; - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok(()) + Ok(()) + }) } pub fn enable_ad5675_gpioe() -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_CY8C9560A_CHANNEL)?; + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_CY8C9560A_CHANNEL)?; - let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); - let mut value = cy8c9560a.read_port_status(3)?; - value = (value & !0x10) | 1 << 4; - cy8c9560a.set_output_port(3, value)?; + let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); + let mut value = cy8c9560a.read_port_status(3)?; + value = (value & !0x10) | 1 << 4; + cy8c9560a.set_output_port(3, value)?; - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok(()) + Ok(()) + }) } // GP7[7]: TCA_CLK_SC_EN // GP7[6]: TCA_CLK_OUT_EN pub fn enable_nb3v9312c_gpioe() -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_CY8C9560A_CHANNEL)?; + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_CY8C9560A_CHANNEL)?; - let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); - let mut value = cy8c9560a.read_port_status(7)?; - value = value | 0xC0; - cy8c9560a.set_output_port(7, value)?; + let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); + let mut value = cy8c9560a.read_port_status(7)?; + value = value | 0xC0; + cy8c9560a.set_output_port(7, value)?; - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok(()) + Ok(()) + }) } pub fn disable_nb3v9312c_gpioe() -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_CY8C9560A_CHANNEL)?; + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_CY8C9560A_CHANNEL)?; - let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); - let mut value = cy8c9560a.read_port_status(7)?; - value = value & 0x3F; - cy8c9560a.set_output_port(7, value)?; + let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); + let mut value = cy8c9560a.read_port_status(7)?; + value = value & 0x3F; + cy8c9560a.set_output_port(7, value)?; - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok(()) + Ok(()) + }) } /* @@ -227,21 +240,23 @@ pub fn disable_nb3v9312c_gpioe() -> Result<(), RBError> { */ pub fn rf_input_select_gpioe(mode: u8) -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_CY8C9560A_CHANNEL)?; - - let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); - drs_ch1_input_select(cy8c9560a, mode)?; - drs_ch2_input_select(cy8c9560a, mode)?; - drs_ch3_input_select(cy8c9560a, mode)?; - drs_ch4_input_select(cy8c9560a, mode)?; - drs_ch5_input_select(cy8c9560a, mode)?; - drs_ch6_input_select(cy8c9560a, mode)?; - drs_ch7_input_select(cy8c9560a, mode)?; - drs_ch8_input_select(cy8c9560a, mode)?; - drs_ch9_input_select(cy8c9560a, mode)?; - - Ok(()) + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_CY8C9560A_CHANNEL)?; + + let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); + drs_ch1_input_select(cy8c9560a, mode)?; + drs_ch2_input_select(cy8c9560a, mode)?; + drs_ch3_input_select(cy8c9560a, mode)?; + drs_ch4_input_select(cy8c9560a, mode)?; + drs_ch5_input_select(cy8c9560a, mode)?; + drs_ch6_input_select(cy8c9560a, mode)?; + drs_ch7_input_select(cy8c9560a, mode)?; + drs_ch8_input_select(cy8c9560a, mode)?; + drs_ch9_input_select(cy8c9560a, mode)?; + + Ok(()) + }) } // GP7[5] = EN @@ -480,198 +495,218 @@ fn drs_ch9_input_select(gpioe: CY8C9560A, mode: u8) -> Result<(), RBError> { pub fn device_info_gpioe() -> Result<(u8, u8, Vec), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_CY8C9560A_CHANNEL)?; - - let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); - let (device_family, device_setting) = cy8c9560a.read_device_info()?; - let mut port_status = Vec::new(); - for i in 0..=7 { - port_status.push(cy8c9560a.read_port_status(i)?); - } - - Ok(( - device_family, - device_setting, - port_status, - )) + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_CY8C9560A_CHANNEL)?; + + let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); + let (device_family, device_setting) = cy8c9560a.read_device_info()?; + let mut port_status = Vec::new(); + for i in 0..=7 { + port_status.push(cy8c9560a.read_port_status(i)?); + } + + Ok(( + device_family, + device_setting, + port_status, + )) + }) } pub fn read_port_gpioe() -> Result, RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_CY8C9560A_CHANNEL)?; + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_CY8C9560A_CHANNEL)?; - let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); - let mut gp = Vec::new(); - for i in 0..=7 { - gp.push(cy8c9560a.read_port_status(i)?); - } + let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); + let mut gp = Vec::new(); + for i in 0..=7 { + gp.push(cy8c9560a.read_port_status(i)?); + } - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok(gp) + Ok(gp) + }) } pub fn set_rf_switch_gpioe(mode: u8) -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_CY8C9560A_CHANNEL)?; - - let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); - - for i in 0..=8 { - if i == 8 { - match mode { - 0 => cy8c9560a.set_rf_switch(i, 0)?, - _ => cy8c9560a.set_rf_switch(i, 2)?, + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_CY8C9560A_CHANNEL)?; + + let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); + + for i in 0..=8 { + if i == 8 { + match mode { + 0 => cy8c9560a.set_rf_switch(i, 0)?, + _ => cy8c9560a.set_rf_switch(i, 2)?, + } + } else { + cy8c9560a.set_rf_switch(i, mode)? } - } else { - cy8c9560a.set_rf_switch(i, mode)? } - } - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok(()) + Ok(()) + }) } pub fn enable_tcal_clock_gpioe(mode: u8) -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_CY8C9560A_CHANNEL)?; + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_CY8C9560A_CHANNEL)?; - let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); - if mode == 1 { - cy8c9560a.enable_tcal_clock()?; - } + let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); + if mode == 1 { + cy8c9560a.enable_tcal_clock()?; + } - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok(()) + Ok(()) + }) } pub fn disable_tcal_clock_gpioe() -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_CY8C9560A_CHANNEL)?; + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_CY8C9560A_CHANNEL)?; - let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); - cy8c9560a.disable_tcal_clock()?; + let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); + cy8c9560a.disable_tcal_clock()?; - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok(()) + Ok(()) + }) } pub fn dac_reset_gpioe() -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_CY8C9560A_CHANNEL)?; + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_CY8C9560A_CHANNEL)?; - let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); - let mut value = cy8c9560a.read_port_status(3)?; - value = (value & !0x10) | 0x10; - cy8c9560a.set_output_port(3, value)?; + let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); + let mut value = cy8c9560a.read_port_status(3)?; + value = (value & !0x10) | 0x10; + cy8c9560a.set_output_port(3, value)?; - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok(()) + Ok(()) + }) } pub fn program_eeprom_gpioe() -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_CY8C9560A_CHANNEL)?; + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_CY8C9560A_CHANNEL)?; - let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); - let enable_register = cy8c9560a.read_enable_register()?; - if (enable_register & 0x02) != 0x02 { - cy8c9560a.enable_eeprom()?; - } + let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); + let enable_register = cy8c9560a.read_enable_register()?; + if (enable_register & 0x02) != 0x02 { + cy8c9560a.enable_eeprom()?; + } - cy8c9560a.store_config_eeprom_por()?; + cy8c9560a.store_config_eeprom_por()?; - i2c_mux.reset()?; - - Ok(()) + i2c_mux.reset()?; + + Ok(()) + }) } pub fn reset_eeprom_gpioe() -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_CY8C9560A_CHANNEL)?; + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_CY8C9560A_CHANNEL)?; - let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); - let enable_register = cy8c9560a.read_enable_register()?; - if (enable_register & 0x02) != 0x02 { - cy8c9560a.enable_eeprom()?; - } + let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); + let enable_register = cy8c9560a.read_enable_register()?; + if (enable_register & 0x02) != 0x02 { + cy8c9560a.enable_eeprom()?; + } - cy8c9560a.reset_config_eeprom_por()?; + cy8c9560a.reset_config_eeprom_por()?; - i2c_mux.reset()?; - - Ok(()) + i2c_mux.reset()?; + + Ok(()) + }) } pub fn reset_gpioe() -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_CY8C9560A_CHANNEL)?; + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_CY8C9560A_CHANNEL)?; - let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); - cy8c9560a.initialize_all_outputs()?; + let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); + cy8c9560a.initialize_all_outputs()?; - i2c_mux.reset()?; - - Ok(()) + i2c_mux.reset()?; + + Ok(()) + }) } pub fn read_rf_input_port(ch: u8) -> Result { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux.select(RB_CY8C9560A_CHANNEL)?; + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + i2c_mux.select(RB_CY8C9560A_CHANNEL)?; - let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); - let mut rf_input_port: u8 = Default::default(); - match ch { + let cy8c9560a = cy8c9560a::CY8C9560A::new(I2C_BUS, RB_CY8C9560A_ADDRESS); + let mut rf_input_port: u8 = Default::default(); + match ch { - 1 => { - rf_input_port = cy8c9560a.read_port_status(7)?; - rf_input_port = (rf_input_port & 0x30) >> 4; + 1 => { + rf_input_port = cy8c9560a.read_port_status(7)?; + rf_input_port = (rf_input_port & 0x30) >> 4; + } + 2 => { + rf_input_port = cy8c9560a.read_port_status(7)?; + rf_input_port = (rf_input_port & 0x0C) >> 2; + } + 3 => { + rf_input_port = cy8c9560a.read_port_status(7)?; + rf_input_port = rf_input_port & 0x03; + } + 4 => { + rf_input_port = cy8c9560a.read_port_status(2)?; + rf_input_port = rf_input_port & 0x03; + } + 5 => { + rf_input_port = cy8c9560a.read_port_status(5)?; + rf_input_port = rf_input_port & 0x03; + rf_input_port = ((rf_input_port & 0x02) >> 1) | ((rf_input_port & 0x01) << 1) + } + 6 => { + rf_input_port = cy8c9560a.read_port_status(5)?; + rf_input_port = (rf_input_port & 0x30) >> 4; + } + 7 => { + rf_input_port = cy8c9560a.read_port_status(4)?; + rf_input_port = (rf_input_port & 0xC0) >> 6; + rf_input_port = ((rf_input_port & 0x02) >> 1) | ((rf_input_port & 0x01) << 1) + } + 8 => { + rf_input_port = cy8c9560a.read_port_status(4)?; + rf_input_port = (rf_input_port & 0x30) >> 4; + rf_input_port = ((rf_input_port & 0x02) >> 1) | ((rf_input_port & 0x01) << 1) + } + 9 => { + rf_input_port = cy8c9560a.read_port_status(4)?; + rf_input_port = (rf_input_port & 0x0C) >> 2; + rf_input_port = ((rf_input_port & 0x02) >> 1) | ((rf_input_port & 0x01) << 1) + } + _ => {} } - 2 => { - rf_input_port = cy8c9560a.read_port_status(7)?; - rf_input_port = (rf_input_port & 0x0C) >> 2; - } - 3 => { - rf_input_port = cy8c9560a.read_port_status(7)?; - rf_input_port = rf_input_port & 0x03; - } - 4 => { - rf_input_port = cy8c9560a.read_port_status(2)?; - rf_input_port = rf_input_port & 0x03; - } - 5 => { - rf_input_port = cy8c9560a.read_port_status(5)?; - rf_input_port = rf_input_port & 0x03; - rf_input_port = ((rf_input_port & 0x02) >> 1) | ((rf_input_port & 0x01) << 1) - } - 6 => { - rf_input_port = cy8c9560a.read_port_status(5)?; - rf_input_port = (rf_input_port & 0x30) >> 4; - } - 7 => { - rf_input_port = cy8c9560a.read_port_status(4)?; - rf_input_port = (rf_input_port & 0xC0) >> 6; - rf_input_port = ((rf_input_port & 0x02) >> 1) | ((rf_input_port & 0x01) << 1) - } - 8 => { - rf_input_port = cy8c9560a.read_port_status(4)?; - rf_input_port = (rf_input_port & 0x30) >> 4; - rf_input_port = ((rf_input_port & 0x02) >> 1) | ((rf_input_port & 0x01) << 1) - } - 9 => { - rf_input_port = cy8c9560a.read_port_status(4)?; - rf_input_port = (rf_input_port & 0x0C) >> 2; - rf_input_port = ((rf_input_port & 0x02) >> 1) | ((rf_input_port & 0x01) << 1) - } - _ => {} - } - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok(rf_input_port) + Ok(rf_input_port) + }) } \ No newline at end of file diff --git a/src/rb_control/rb_info.rs b/src/rb_control/rb_info.rs index 660a8be..eb1173b 100644 --- a/src/rb_control/rb_info.rs +++ b/src/rb_control/rb_info.rs @@ -4,9 +4,9 @@ use i2cdev::linux::LinuxI2CDevice; use crate::constant::*; use crate::memory::read_control_reg; - use crate::helper::rb_type::{RBInfo, RBError}; use crate::rb_control::rb_mode; +use crate::i2c_bus_lock::with_i2c_bus_lock; impl RBInfo { pub fn new() -> Self { @@ -53,25 +53,27 @@ impl RBInfo { Ok(board_id) } pub fn read_sub_board() -> Result { - let sub_board: u8; - - let mut ltb_i2c = LinuxI2CDevice::new(&format!("/dev/i2c-{}", I2C_BUS), LTB_TRENZ_ADDRESS)?; - let mut pb_i2c = LinuxI2CDevice::new(&format!("/dev/i2c-{}", I2C_BUS), PB_PCA9548A_ADDRESS)?; - - let ltb_on = ltb_i2c.smbus_read_byte().is_ok(); - let pb_on = pb_i2c.smbus_read_byte().is_ok(); - - if ltb_on && !pb_on { - sub_board = 1; - } else if !ltb_on && pb_on { - sub_board = 2; - } else if ltb_on && pb_on { - sub_board = 3; - } else { - sub_board = 0; - } - - Ok(sub_board) + with_i2c_bus_lock(|| { + let sub_board: u8; + + let mut ltb_i2c = LinuxI2CDevice::new(&format!("/dev/i2c-{}", I2C_BUS), LTB_TRENZ_ADDRESS)?; + let mut pb_i2c = LinuxI2CDevice::new(&format!("/dev/i2c-{}", I2C_BUS), PB_PCA9548A_ADDRESS)?; + + let ltb_on = ltb_i2c.smbus_read_byte().is_ok(); + let pb_on = pb_i2c.smbus_read_byte().is_ok(); + + if ltb_on && !pb_on { + sub_board = 1; + } else if !ltb_on && pb_on { + sub_board = 2; + } else if ltb_on && pb_on { + sub_board = 3; + } else { + sub_board = 0; + } + + Ok(sub_board) + }) } pub fn read_lol() -> Result { let mut lol = read_control_reg(LOSS_OF_LOCK)? as u8; diff --git a/src/rb_control/rb_mag.rs b/src/rb_control/rb_mag.rs index 2a2485b..fc14484 100644 --- a/src/rb_control/rb_mag.rs +++ b/src/rb_control/rb_mag.rs @@ -1,6 +1,7 @@ use crate::constant::*; use crate::helper::rb_type::{RBMag, RBError}; use crate::device::{lis3mdltr, pca9548a}; +use crate::i2c_bus_lock::with_i2c_bus_lock; impl RBMag { pub fn new() -> Self { @@ -16,30 +17,34 @@ impl RBMag { } } pub fn read_mag() -> Result { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_1); - i2c_mux.select(RB_LIS3MDLTR_CHANNEL)?; + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_1); + i2c_mux.select(RB_LIS3MDLTR_CHANNEL)?; - let lis3mdltr = lis3mdltr::LIS3MDLTR::new(I2C_BUS, RB_LIS3MDLTR_ADDRESS); - lis3mdltr.configure()?; - let mag_xyz = lis3mdltr.read_mag()?; + let lis3mdltr = lis3mdltr::LIS3MDLTR::new(I2C_BUS, RB_LIS3MDLTR_ADDRESS); + lis3mdltr.configure()?; + let mag_xyz = lis3mdltr.read_mag()?; - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok( - RBMag { - mag_xyz, - } - ) + Ok( + RBMag { + mag_xyz, + } + ) + }) } } pub fn config_mag() -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_1); - i2c_mux.select(RB_LIS3MDLTR_CHANNEL)?; - let lis3mdltr = lis3mdltr::LIS3MDLTR::new(I2C_BUS, RB_LIS3MDLTR_ADDRESS); - lis3mdltr.configure()?; + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_1); + i2c_mux.select(RB_LIS3MDLTR_CHANNEL)?; + let lis3mdltr = lis3mdltr::LIS3MDLTR::new(I2C_BUS, RB_LIS3MDLTR_ADDRESS); + lis3mdltr.configure()?; - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok(()) + Ok(()) + }) } \ No newline at end of file diff --git a/src/rb_control/rb_mode.rs b/src/rb_control/rb_mode.rs index 3d96e0d..c8bf61c 100644 --- a/src/rb_control/rb_mode.rs +++ b/src/rb_control/rb_mode.rs @@ -5,52 +5,67 @@ use crate::rb_control::{rb_dac, rb_input, rb_gpioe}; use std::thread::sleep; use std::time::Duration; +const MODE_MAX_RETRIES: usize = 5; +const MODE_RETRY_DELAY_MS: u64 = 10; + pub fn select_noi_mode() -> Result<(), RBError> { - rb_dac::dac_noi_mode()?; - rb_input::disable_rf_input()?; + for _ in 0..MODE_MAX_RETRIES { + rb_dac::dac_noi_mode()?; + rb_input::disable_rf_input()?; + + if verify_input_mode("NOI")? { + return Ok(()); + } - while (verify_input_mode("NOI")?) == false { - sleep(Duration::from_millis(10)); - select_noi_mode()?; + sleep(Duration::from_millis(MODE_RETRY_DELAY_MS)); } - Ok(()) + Err(RBError::InvalidInputMode) } pub fn select_vcal_mode() -> Result<(), RBError> { - rb_dac::dac_vcal_mode()?; - rb_input::disable_rf_input()?; + for _ in 0..MODE_MAX_RETRIES { + rb_dac::dac_vcal_mode()?; + rb_input::disable_rf_input()?; - while (verify_input_mode("VCAL")?) == false { - sleep(Duration::from_millis(10)); - select_noi_mode()?; + if verify_input_mode("VCAL")? { + return Ok(()); + } + + sleep(Duration::from_millis(MODE_RETRY_DELAY_MS)); } - Ok(()) + Err(RBError::InvalidInputMode) } pub fn select_tcal_mode() -> Result<(), RBError> { - rb_dac::dac_tcal_mode()?; - rb_input::enable_tca_input()?; + for _ in 0..MODE_MAX_RETRIES { + rb_dac::dac_tcal_mode()?; + rb_input::enable_tca_input()?; - while (verify_input_mode("TCAL")?) == false { - sleep(Duration::from_millis(10)); - select_noi_mode()?; + if verify_input_mode("TCAL")? { + return Ok(()); + } + + sleep(Duration::from_millis(MODE_RETRY_DELAY_MS)); } - Ok(()) + Err(RBError::InvalidInputMode) } pub fn select_sma_mode() -> Result<(), RBError> { - rb_dac::dac_sma_mode()?; - rb_input::enable_sma_input()?; + for _ in 0..MODE_MAX_RETRIES { + rb_dac::dac_sma_mode()?; + rb_input::enable_sma_input()?; - while (verify_input_mode("SMA")?) == false { - sleep(Duration::from_millis(10)); - select_noi_mode()?; - } + if verify_input_mode("SMA")? { + return Ok(()); + } - Ok(()) + sleep(Duration::from_millis(MODE_RETRY_DELAY_MS)); + } + + Err(RBError::InvalidInputMode) } pub fn read_input_mode() -> Result { diff --git a/src/rb_control/rb_ph.rs b/src/rb_control/rb_ph.rs index 03d3f99..d30d3e2 100644 --- a/src/rb_control/rb_ph.rs +++ b/src/rb_control/rb_ph.rs @@ -1,6 +1,7 @@ use crate::constant::*; use crate::helper::rb_type::{RBPh, RBError}; use crate::device::{bme280, pca9548a}; +use crate::i2c_bus_lock::with_i2c_bus_lock; impl RBPh { pub fn new() -> Self { @@ -17,33 +18,37 @@ impl RBPh { } } pub fn read_ph() -> Result { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_1); + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_1); - i2c_mux.select(RB_BME280_CHANNEL)?; - let bme280 = bme280::BME280::new(I2C_BUS, RB_BME280_ADDRESS); - bme280.configure()?; - let ph = bme280.read()?; - let pressure = ph[0]; - let humidity = ph[1]; + i2c_mux.select(RB_BME280_CHANNEL)?; + let bme280 = bme280::BME280::new(I2C_BUS, RB_BME280_ADDRESS); + bme280.configure()?; + let ph = bme280.read()?; + let pressure = ph[0]; + let humidity = ph[1]; - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok( - RBPh { - pressure, - humidity, - } - ) + Ok( + RBPh { + pressure, + humidity, + } + ) + }) } } pub fn config_ph() -> Result<(), RBError> { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_1); - i2c_mux.select(RB_BME280_CHANNEL)?; - let bme280 = bme280::BME280::new(I2C_BUS, RB_BME280_ADDRESS); - bme280.configure()?; + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_1); + i2c_mux.select(RB_BME280_CHANNEL)?; + let bme280 = bme280::BME280::new(I2C_BUS, RB_BME280_ADDRESS); + bme280.configure()?; - i2c_mux.reset()?; + i2c_mux.reset()?; - Ok(()) + Ok(()) + }) } \ No newline at end of file diff --git a/src/rb_control/rb_temp.rs b/src/rb_control/rb_temp.rs index 855bca5..ae7a8e9 100644 --- a/src/rb_control/rb_temp.rs +++ b/src/rb_control/rb_temp.rs @@ -2,6 +2,7 @@ use crate::constant::*; use crate::memory::read_control_reg; use crate::helper::rb_type::{RBTemp, RBError}; use crate::device::{bme280, lis3mdltr, pca9548a, tmp112}; +use crate::i2c_bus_lock::with_i2c_bus_lock; impl RBTemp { pub fn new() -> Self { @@ -23,96 +24,104 @@ impl RBTemp { } pub fn read_temp() -> Result { - let zynq_temp_adc = read_control_reg(RB_TEMP)?; - let zynq_temp = (((zynq_temp_adc & 4095) as f32 * 503.975) / 4096.0) - 273.15; + with_i2c_bus_lock(|| { + let zynq_temp_adc = read_control_reg(RB_TEMP)?; + let zynq_temp = (((zynq_temp_adc & 4095) as f32 * 503.975) / 4096.0) - 273.15; + + let i2c_mux_1 = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_1); + let i2c_mux_2 = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + + i2c_mux_1.select(RB_DRS_TMP112_CHANNEL)?; + let drs_tmp112 = tmp112::TMP112::new(I2C_BUS, RB_DRS_TMP112_ADDRESS); + drs_tmp112.config()?; + let drs_temp = drs_tmp112.read()?; + + i2c_mux_1.select(RB_LIS3MDLTR_CHANNEL)?; + let lis3mdltr = lis3mdltr::LIS3MDLTR::new(I2C_BUS, RB_LIS3MDLTR_ADDRESS); + lis3mdltr.configure()?; + let lis3mdltr_temp = lis3mdltr.read_temp()?; + + i2c_mux_1.select(RB_BME280_CHANNEL)?; + let bme280 = bme280::BME280::new(I2C_BUS, RB_BME280_ADDRESS); + bme280.configure()?; + let bme280_temp = bme280.read_all()?[0]; + + i2c_mux_2.select(RB_CLK_TMP112_CHANNEL)?; + let clk_tmp112 = tmp112::TMP112::new(I2C_BUS, RB_CLK_TMP112_ADDRESS); + clk_tmp112.config()?; + let clk_temp = clk_tmp112.read()?; + + i2c_mux_2.select(RB_ADC_TMP112_CHANNEL)?; + let adc_tmp112 = tmp112::TMP112::new(I2C_BUS, RB_ADC_TMP112_ADDRESS); + adc_tmp112.config()?; + let adc_temp = adc_tmp112.read()?; + + i2c_mux_1.reset()?; + i2c_mux_2.reset()?; + + Ok( + RBTemp { + zynq_temp, + drs_temp, + clk_temp, + adc_temp, + bme280_temp, + lis3mdltr_temp, + } + ) + }) + } + pub fn read_drs_temp() -> Result { + with_i2c_bus_lock(|| { + let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_1); + i2c_mux.select(RB_DRS_TMP112_CHANNEL)?; + let drs_tmp112 = tmp112::TMP112::new(I2C_BUS, RB_DRS_TMP112_ADDRESS); + drs_tmp112.config()?; + let drs_temp = drs_tmp112.read()?; + + i2c_mux.reset()?; + Ok(drs_temp) + }) + } +} + +pub fn config_temp() -> Result<(), RBError> { + with_i2c_bus_lock(|| { let i2c_mux_1 = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_1); let i2c_mux_2 = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); i2c_mux_1.select(RB_DRS_TMP112_CHANNEL)?; let drs_tmp112 = tmp112::TMP112::new(I2C_BUS, RB_DRS_TMP112_ADDRESS); drs_tmp112.config()?; - let drs_temp = drs_tmp112.read()?; - - i2c_mux_1.select(RB_LIS3MDLTR_CHANNEL)?; - let lis3mdltr = lis3mdltr::LIS3MDLTR::new(I2C_BUS, RB_LIS3MDLTR_ADDRESS); - lis3mdltr.configure()?; - let lis3mdltr_temp = lis3mdltr.read_temp()?; - - i2c_mux_1.select(RB_BME280_CHANNEL)?; - let bme280 = bme280::BME280::new(I2C_BUS, RB_BME280_ADDRESS); - bme280.configure()?; - let bme280_temp = bme280.read_all()?[0]; i2c_mux_2.select(RB_CLK_TMP112_CHANNEL)?; let clk_tmp112 = tmp112::TMP112::new(I2C_BUS, RB_CLK_TMP112_ADDRESS); clk_tmp112.config()?; - let clk_temp = clk_tmp112.read()?; i2c_mux_2.select(RB_ADC_TMP112_CHANNEL)?; let adc_tmp112 = tmp112::TMP112::new(I2C_BUS, RB_ADC_TMP112_ADDRESS); adc_tmp112.config()?; - let adc_temp = adc_tmp112.read()?; i2c_mux_1.reset()?; i2c_mux_2.reset()?; - Ok( - RBTemp { - zynq_temp, - drs_temp, - clk_temp, - adc_temp, - bme280_temp, - lis3mdltr_temp, - } - ) - } - pub fn read_drs_temp() -> Result { + Ok(()) + }) +} + +pub fn read_drs_temp_raw() -> Result { + with_i2c_bus_lock(|| { let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_1); i2c_mux.select(RB_DRS_TMP112_CHANNEL)?; let drs_tmp112 = tmp112::TMP112::new(I2C_BUS, RB_DRS_TMP112_ADDRESS); drs_tmp112.config()?; - let drs_temp = drs_tmp112.read()?; + let drs_temp_raw = drs_tmp112.read_raw()?; i2c_mux.reset()?; - Ok(drs_temp) - } -} - -pub fn config_temp() -> Result<(), RBError> { - let i2c_mux_1 = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_1); - let i2c_mux_2 = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - - i2c_mux_1.select(RB_DRS_TMP112_CHANNEL)?; - let drs_tmp112 = tmp112::TMP112::new(I2C_BUS, RB_DRS_TMP112_ADDRESS); - drs_tmp112.config()?; - - i2c_mux_2.select(RB_CLK_TMP112_CHANNEL)?; - let clk_tmp112 = tmp112::TMP112::new(I2C_BUS, RB_CLK_TMP112_ADDRESS); - clk_tmp112.config()?; - - i2c_mux_2.select(RB_ADC_TMP112_CHANNEL)?; - let adc_tmp112 = tmp112::TMP112::new(I2C_BUS, RB_ADC_TMP112_ADDRESS); - adc_tmp112.config()?; - - i2c_mux_1.reset()?; - i2c_mux_2.reset()?; - - Ok(()) -} - -pub fn read_drs_temp_raw() -> Result { - let i2c_mux = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_1); - i2c_mux.select(RB_DRS_TMP112_CHANNEL)?; - let drs_tmp112 = tmp112::TMP112::new(I2C_BUS, RB_DRS_TMP112_ADDRESS); - drs_tmp112.config()?; - let drs_temp_raw = drs_tmp112.read_raw()?; - - i2c_mux.reset()?; - - Ok(drs_temp_raw) + Ok(drs_temp_raw) + }) } pub fn to_json() -> Result { diff --git a/src/rb_control/rb_vcp.rs b/src/rb_control/rb_vcp.rs index 6fa750d..bfd1a39 100644 --- a/src/rb_control/rb_vcp.rs +++ b/src/rb_control/rb_vcp.rs @@ -1,6 +1,7 @@ use crate::constant::*; use crate::helper::rb_type::{RBVcp, RBError}; use crate::device::{ina226, max11645, pca9548a}; +use crate::i2c_bus_lock::with_i2c_bus_lock; impl RBVcp { pub fn new() -> Self { @@ -23,164 +24,167 @@ impl RBVcp { } } pub fn read_vcp() -> Result { + with_i2c_bus_lock(|| { + let i2c_mux_1 = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_1); + let i2c_mux_2 = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); + + i2c_mux_1.select(RB_ZYNQ_INA226_CHANNEL)?; + let zynq_ina226 = ina226::INA226::new(I2C_BUS, RB_ZYNQ_INA226_ADDRESS, RB_ZYNQ_INA226_RSHUNT, RB_ZYNQ_INA226_MEC,); + zynq_ina226.configure()?; + let zynq_vcp = zynq_ina226.read()?; + + i2c_mux_1.select(RB_P3V3_INA226_CHANNEL)?; + let p3v3_ina226 = ina226::INA226::new(I2C_BUS, RB_P3V3_INA226_ADDRESS, RB_P3V3_INA226_RSHUNT, RB_P3V3_INA226_MEC); + p3v3_ina226.configure()?; + let p3v3_vcp =p3v3_ina226.read()?; + + i2c_mux_1.select(RB_P3V5_INA226_CHANNEL)?; + let p3v5_ina226 = ina226::INA226::new(I2C_BUS, RB_P3V5_INA226_ADDRESS, RB_P3V5_INA226_RSHUNT, RB_P3V5_INA226_MEC); + p3v5_ina226.configure()?; + let p3v5_vcp = p3v5_ina226.read()?; + + i2c_mux_1.select(RB_MAX11645_CHANNEL)?; + let max11645 = max11645::MAX11645::new(I2C_BUS, RB_MAX11645_ADDRESS); + max11645.setup()?; + let n1v5_voltage = max11645.read(RB_N1V5_VOLTAGE_INA200_CHANNEL)? * -1.0; + let n1v5_current = max11645.read(RB_N1V5_CURRENT_INA200_CHANNEL)? / 20.0 / 0.039; + let n1v5_power = n1v5_voltage.abs() * n1v5_current; + let n1v5_vcp = [n1v5_voltage, n1v5_current, n1v5_power]; + + i2c_mux_1.select(RB_DRS_DVDD_INA226_CHANNEL)?; + let drs_dvdd_ina226 = ina226::INA226::new(I2C_BUS, RB_DRS_DVDD_INA226_ADDRESS, RB_DRS_DVDD_INA226_RSHUNT, RB_DRS_DVDD_INA226_MEC); + drs_dvdd_ina226.configure()?; + let drs_dvdd_vcp = drs_dvdd_ina226.read()?; + + i2c_mux_2.select(RB_DRS_AVDD_INA226_CHANNEL)?; + let drs_avdd_ina226 = ina226::INA226::new(I2C_BUS, RB_DRS_AVDD_INA226_ADDRESS, RB_DRS_AVDD_INA226_RSHUNT, RB_DRS_AVDD_INA226_MEC); + drs_avdd_ina226.configure()?; + let drs_avdd_vcp = drs_avdd_ina226.read()?; + + i2c_mux_2.select(RB_ADC_DVDD_INA226_CHANNEL)?; + let adc_dvdd_ina226 = ina226::INA226::new(I2C_BUS, RB_ADC_DVDD_INA226_ADDRESS, RB_ADC_DVDD_INA226_RSHUNT, RB_ADC_DVDD_INA226_MEC); + adc_dvdd_ina226.configure()?; + let adc_dvdd_vcp = adc_dvdd_ina226.read()?; + + i2c_mux_2.select(RB_ADC_AVDD_INA226_CHANNEL)?; + let adc_avdd_ina226 = ina226::INA226::new(I2C_BUS, RB_ADC_AVDD_INA226_ADDRESS, RB_ADC_AVDD_INA226_RSHUNT, RB_ADC_AVDD_INA226_MEC); + adc_avdd_ina226.configure()?; + let adc_avdd_vcp = adc_avdd_ina226.read()?; + + i2c_mux_1.reset()?; + i2c_mux_2.reset()?; + + Ok( + RBVcp { + zynq_vcp, + p3v3_vcp, + p3v5_vcp, + n1v5_vcp, + drs_dvdd_vcp, + drs_avdd_vcp, + adc_dvdd_vcp, + adc_avdd_vcp, + } + ) + }) + } +} + +pub fn config_vcp() -> Result<(), RBError> { + with_i2c_bus_lock(|| { let i2c_mux_1 = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_1); let i2c_mux_2 = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - i2c_mux_1.select(RB_ZYNQ_INA226_CHANNEL)?; - let zynq_ina226 = ina226::INA226::new(I2C_BUS, RB_ZYNQ_INA226_ADDRESS, RB_ZYNQ_INA226_RSHUNT, RB_ZYNQ_INA226_MEC,); - zynq_ina226.configure()?; - let zynq_vcp = zynq_ina226.read()?; + i2c_mux_1.select(RB_DRS_DVDD_INA226_CHANNEL)?; + let drs_dvdd_ina226 = ina226::INA226::new( + I2C_BUS, + RB_DRS_DVDD_INA226_ADDRESS, + RB_DRS_DVDD_INA226_RSHUNT, + RB_DRS_DVDD_INA226_MEC, + ); + for _ in 0..3 { + drs_dvdd_ina226.configure()?; + drs_dvdd_ina226.read()?; + } i2c_mux_1.select(RB_P3V3_INA226_CHANNEL)?; - let p3v3_ina226 = ina226::INA226::new(I2C_BUS, RB_P3V3_INA226_ADDRESS, RB_P3V3_INA226_RSHUNT, RB_P3V3_INA226_MEC); - p3v3_ina226.configure()?; - let p3v3_vcp =p3v3_ina226.read()?; + let p3v3_ina226 = ina226::INA226::new( + I2C_BUS, + RB_P3V3_INA226_ADDRESS, + RB_P3V3_INA226_RSHUNT, + RB_P3V3_INA226_MEC, + ); + for _ in 0..3 { + p3v3_ina226.configure()?; + p3v3_ina226.read()?; + } + + i2c_mux_1.select(RB_ZYNQ_INA226_CHANNEL)?; + let zynq_ina226 = ina226::INA226::new( + I2C_BUS, + RB_ZYNQ_INA226_ADDRESS, + RB_ZYNQ_INA226_RSHUNT, + RB_ZYNQ_INA226_MEC, + ); + zynq_ina226.configure()?; + zynq_ina226.read()?; + zynq_ina226.read()?; i2c_mux_1.select(RB_P3V5_INA226_CHANNEL)?; - let p3v5_ina226 = ina226::INA226::new(I2C_BUS, RB_P3V5_INA226_ADDRESS, RB_P3V5_INA226_RSHUNT, RB_P3V5_INA226_MEC); - p3v5_ina226.configure()?; - let p3v5_vcp = p3v5_ina226.read()?; + let p3v5_ina226 = ina226::INA226::new( + I2C_BUS, + RB_P3V5_INA226_ADDRESS, + RB_P3V5_INA226_RSHUNT, + RB_P3V5_INA226_MEC, + ); + for _ in 0..3 { + p3v5_ina226.configure()?; + p3v5_ina226.read()?; + } - i2c_mux_1.select(RB_MAX11645_CHANNEL)?; - let max11645 = max11645::MAX11645::new(I2C_BUS, RB_MAX11645_ADDRESS); - max11645.setup()?; - let n1v5_voltage = max11645.read(RB_N1V5_VOLTAGE_INA200_CHANNEL)? * -1.0; - let n1v5_current = max11645.read(RB_N1V5_CURRENT_INA200_CHANNEL)? / 20.0 / 0.039; - let n1v5_power = n1v5_voltage.abs() * n1v5_current; - let n1v5_vcp = [n1v5_voltage, n1v5_current, n1v5_power]; + i2c_mux_2.select(RB_ADC_DVDD_INA226_CHANNEL)?; + let adc_dvdd_ina226 = ina226::INA226::new( + I2C_BUS, + RB_ADC_DVDD_INA226_ADDRESS, + RB_ADC_DVDD_INA226_RSHUNT, + RB_ADC_DVDD_INA226_MEC, + ); + for _ in 0..3 { + adc_dvdd_ina226.configure()?; + adc_dvdd_ina226.read()?; + } - i2c_mux_1.select(RB_DRS_DVDD_INA226_CHANNEL)?; - let drs_dvdd_ina226 = ina226::INA226::new(I2C_BUS, RB_DRS_DVDD_INA226_ADDRESS, RB_DRS_DVDD_INA226_RSHUNT, RB_DRS_DVDD_INA226_MEC); - drs_dvdd_ina226.configure()?; - let drs_dvdd_vcp = drs_dvdd_ina226.read()?; + i2c_mux_2.select(RB_ADC_AVDD_INA226_CHANNEL)?; + let adc_avdd_ina226 = ina226::INA226::new( + I2C_BUS, + RB_ADC_AVDD_INA226_ADDRESS, + RB_ADC_AVDD_INA226_RSHUNT, + RB_ADC_AVDD_INA226_MEC, + ); + for _ in 0..3 { + adc_avdd_ina226.configure()?; + adc_avdd_ina226.read()?; + } i2c_mux_2.select(RB_DRS_AVDD_INA226_CHANNEL)?; - let drs_avdd_ina226 = ina226::INA226::new(I2C_BUS, RB_DRS_AVDD_INA226_ADDRESS, RB_DRS_AVDD_INA226_RSHUNT, RB_DRS_AVDD_INA226_MEC); - drs_avdd_ina226.configure()?; - let drs_avdd_vcp = drs_avdd_ina226.read()?; - - i2c_mux_2.select(RB_ADC_DVDD_INA226_CHANNEL)?; - let adc_dvdd_ina226 = ina226::INA226::new(I2C_BUS, RB_ADC_DVDD_INA226_ADDRESS, RB_ADC_DVDD_INA226_RSHUNT, RB_ADC_DVDD_INA226_MEC); - adc_dvdd_ina226.configure()?; - let adc_dvdd_vcp = adc_dvdd_ina226.read()?; + let drs_avdd_ina226 = ina226::INA226::new( + I2C_BUS, + RB_DRS_AVDD_INA226_ADDRESS, + RB_DRS_AVDD_INA226_RSHUNT, + RB_DRS_AVDD_INA226_MEC, + ); + for _ in 0..3 { + drs_avdd_ina226.configure()?; + drs_avdd_ina226.read()?; + } - i2c_mux_2.select(RB_ADC_AVDD_INA226_CHANNEL)?; - let adc_avdd_ina226 = ina226::INA226::new(I2C_BUS, RB_ADC_AVDD_INA226_ADDRESS, RB_ADC_AVDD_INA226_RSHUNT, RB_ADC_AVDD_INA226_MEC); - adc_avdd_ina226.configure()?; - let adc_avdd_vcp = adc_avdd_ina226.read()?; + i2c_mux_1.select(RB_MAX11645_CHANNEL)?; + let max11645 = max11645::MAX11645::new(I2C_BUS, RB_MAX11645_ADDRESS); + max11645.setup()?; i2c_mux_1.reset()?; i2c_mux_2.reset()?; - Ok( - RBVcp { - zynq_vcp, - p3v3_vcp, - p3v5_vcp, - n1v5_vcp, - drs_dvdd_vcp, - drs_avdd_vcp, - adc_dvdd_vcp, - adc_avdd_vcp, - } - ) - - } -} - -pub fn config_vcp() -> Result<(), RBError> { - let i2c_mux_1 = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_1); - let i2c_mux_2 = pca9548a::PCA9548A::new(I2C_BUS, RB_PCA9548A_ADDRESS_2); - - i2c_mux_1.select(RB_DRS_DVDD_INA226_CHANNEL)?; - let drs_dvdd_ina226 = ina226::INA226::new( - I2C_BUS, - RB_DRS_DVDD_INA226_ADDRESS, - RB_DRS_DVDD_INA226_RSHUNT, - RB_DRS_DVDD_INA226_MEC, - ); - for _ in 0..3 { - drs_dvdd_ina226.configure()?; - drs_dvdd_ina226.read()?; - } - - i2c_mux_1.select(RB_P3V3_INA226_CHANNEL)?; - let p3v3_ina226 = ina226::INA226::new( - I2C_BUS, - RB_P3V3_INA226_ADDRESS, - RB_P3V3_INA226_RSHUNT, - RB_P3V3_INA226_MEC, - ); - for _ in 0..3 { - p3v3_ina226.configure()?; - p3v3_ina226.read()?; - } - - i2c_mux_1.select(RB_ZYNQ_INA226_CHANNEL)?; - let zynq_ina226 = ina226::INA226::new( - I2C_BUS, - RB_ZYNQ_INA226_ADDRESS, - RB_ZYNQ_INA226_RSHUNT, - RB_ZYNQ_INA226_MEC, - ); - zynq_ina226.configure()?; - zynq_ina226.read()?; - zynq_ina226.read()?; - - i2c_mux_1.select(RB_P3V5_INA226_CHANNEL)?; - let p3v5_ina226 = ina226::INA226::new( - I2C_BUS, - RB_P3V5_INA226_ADDRESS, - RB_P3V5_INA226_RSHUNT, - RB_P3V5_INA226_MEC, - ); - for _ in 0..3 { - p3v5_ina226.configure()?; - p3v5_ina226.read()?; - } - - i2c_mux_2.select(RB_ADC_DVDD_INA226_CHANNEL)?; - let adc_dvdd_ina226 = ina226::INA226::new( - I2C_BUS, - RB_ADC_DVDD_INA226_ADDRESS, - RB_ADC_DVDD_INA226_RSHUNT, - RB_ADC_DVDD_INA226_MEC, - ); - for _ in 0..3 { - adc_dvdd_ina226.configure()?; - adc_dvdd_ina226.read()?; - } - - i2c_mux_2.select(RB_ADC_AVDD_INA226_CHANNEL)?; - let adc_avdd_ina226 = ina226::INA226::new( - I2C_BUS, - RB_ADC_AVDD_INA226_ADDRESS, - RB_ADC_AVDD_INA226_RSHUNT, - RB_ADC_AVDD_INA226_MEC, - ); - for _ in 0..3 { - adc_avdd_ina226.configure()?; - adc_avdd_ina226.read()?; - } - - i2c_mux_2.select(RB_DRS_AVDD_INA226_CHANNEL)?; - let drs_avdd_ina226 = ina226::INA226::new( - I2C_BUS, - RB_DRS_AVDD_INA226_ADDRESS, - RB_DRS_AVDD_INA226_RSHUNT, - RB_DRS_AVDD_INA226_MEC, - ); - for _ in 0..3 { - drs_avdd_ina226.configure()?; - drs_avdd_ina226.read()?; - } - - i2c_mux_1.select(RB_MAX11645_CHANNEL)?; - let max11645 = max11645::MAX11645::new(I2C_BUS, RB_MAX11645_ADDRESS); - max11645.setup()?; - - i2c_mux_1.reset()?; - i2c_mux_2.reset()?; - - Ok(()) + Ok(()) + }) } \ No newline at end of file diff --git a/src/tcpc_control/tcpc_temp.rs b/src/tcpc_control/tcpc_temp.rs index e076287..98d2a1b 100644 --- a/src/tcpc_control/tcpc_temp.rs +++ b/src/tcpc_control/tcpc_temp.rs @@ -1,6 +1,7 @@ use crate::constant::*; -use crate::helper::tcpc_type::{TCPCTemp, TCPCTempError}; +use crate::helper::tcpc_type::{TCPCTemp, TCPCError}; use crate::device::tmp1075; +use crate::i2c_bus_lock::with_i2c_bus_lock; impl TCPCTemp { pub fn new() -> Self { @@ -15,15 +16,17 @@ impl TCPCTemp { } } } - pub fn read_temp() -> Result { - let tcpc_tmp1075 = tmp1075::TMP1075::new(1, TCPC_TMP1075_ADDRESS); - tcpc_tmp1075.config()?; - let tcpc_temp = tcpc_tmp1075.read()?; + pub fn read_temp() -> Result { + with_i2c_bus_lock(|| { + let tcpc_tmp1075 = tmp1075::TMP1075::new(1, TCPC_TMP1075_ADDRESS); + tcpc_tmp1075.config()?; + let tcpc_temp = tcpc_tmp1075.read()?; - Ok( - TCPCTemp { - tcpc_temp, - } - ) + Ok( + TCPCTemp { + tcpc_temp, + } + ) + }) } } \ No newline at end of file diff --git a/src/tcpc_control/tcpc_vcp.rs b/src/tcpc_control/tcpc_vcp.rs index a8d2998..9899f46 100644 --- a/src/tcpc_control/tcpc_vcp.rs +++ b/src/tcpc_control/tcpc_vcp.rs @@ -1,6 +1,7 @@ use crate::constant::*; -use crate::helper::tcpc_type::{TCPCVcp, TCPCVcpError}; +use crate::helper::tcpc_type::{TCPCVcp, TCPCError}; use crate::device::ina219; +use crate::i2c_bus_lock::with_i2c_bus_lock; impl TCPCVcp { pub fn new() -> Self { @@ -15,15 +16,17 @@ impl TCPCVcp { } } } - pub fn read_vcp() -> Result { - let tcpc_ina219 = ina219::INA219::new(1, TCPC_INA219_ADDRESS, TCPC_INA219_RSHUNT, TCPC_INA219_MEC); - tcpc_ina219.configure()?; - let tcpc_vcp = tcpc_ina219.read()?; + pub fn read_vcp() -> Result { + with_i2c_bus_lock(|| { + let tcpc_ina219 = ina219::INA219::new(1, TCPC_INA219_ADDRESS, TCPC_INA219_RSHUNT, TCPC_INA219_MEC); + tcpc_ina219.configure()?; + let tcpc_vcp = tcpc_ina219.read()?; - Ok( - TCPCVcp { - tcpc_vcp, - } - ) + Ok( + TCPCVcp { + tcpc_vcp, + } + ) + }) } } \ No newline at end of file