Skip to content

Commit 8648403

Browse files
committed
add 'visa' feature
1 parent b5667c2 commit 8648403

10 files changed

+106
-10
lines changed

CHANGELOG.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how
1616
Security -- in case of vulnerabilities.
1717
-->
1818

19+
## [0.17.1]
20+
21+
### Added
22+
23+
- VISA support
24+
1925
## [0.17.0]
2026

2127
### Changed
@@ -65,7 +71,8 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how
6571
- Using `read_password`instead of `prompt_password` of rpassword crate (TSP-517)
6672

6773
<!--Version Comparison Links-->
68-
[Unreleased]: https://github.com/tektronix/tsp-toolkit-kic-lib/compare/v0.17.0..HEAD
74+
[Unreleased]: https://github.com/tektronix/tsp-toolkit-kic-lib/compare/v0.17.1..HEAD
75+
[0.17.1]: https://github.com/tektronix/tsp-toolkit-kic-lib/releases/tag/v0.17.1
6976
[0.17.0]: https://github.com/tektronix/tsp-toolkit-kic-lib/releases/tag/v0.17.0
7077
[0.16.1]: https://github.com/tektronix/tsp-toolkit-kic-lib/releases/tag/v0.16.1
7178
[0.15.1]: https://github.com/tektronix/tsp-toolkit-kic-lib/releases/tag/v0.15.1

Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "tsp-toolkit-kic-lib"
33
description = "A library specifically enabling communication to the Keithley product-line of instruments"
4-
version = "0.17.0"
4+
version = "0.17.1"
55
authors = ["Keithley Instruments, LLC"]
66
edition = "2021"
77
repository = "https://github.com/tektronix/tsp-toolkit-kic-lib"
@@ -19,7 +19,10 @@ rusb = "0.9"
1919
chrono = "0.4"
2020
minidom = "0.15"
2121
reqwest = { version = "0.12", features = ["blocking"] }
22-
visa-rs = "0.6.2"
22+
visa-rs = { version = "0.6.2", optional = true }
23+
24+
[features]
25+
visa = ["dep:visa-rs"]
2326

2427
[dev-dependencies]
2528
anyhow = "1"

src/error.rs

+1
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ pub enum InstrumentError {
129129
lang: String,
130130
},
131131

132+
#[cfg(feature = "visa")]
132133
/// An error from the visa driver
133134
#[error("visa error: {source}")]
134135
VisaError {

src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ pub use interface::{connection_addr::ConnectionAddr, usbtmc, Interface};
2222
pub use model::{ki2600, tti, versatest};
2323

2424
pub mod protocol;
25+
pub use protocol::is_visa_installed;

src/model/ki2600.rs

+2
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ impl NonBlock for Instrument {
194194
fn set_nonblocking(&mut self, enable: bool) -> crate::error::Result<()> {
195195
match &mut self.protocol {
196196
Protocol::Raw(r) => r.set_nonblocking(enable),
197+
198+
#[cfg(feature = "visa")]
197199
Protocol::Visa { .. } => Ok(()),
198200
}
199201
}

src/model/ki3700.rs

+2
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ impl NonBlock for Instrument {
164164
fn set_nonblocking(&mut self, enable: bool) -> crate::error::Result<()> {
165165
match &mut self.protocol {
166166
Protocol::Raw(r) => r.set_nonblocking(enable),
167+
168+
#[cfg(feature = "visa")]
167169
Protocol::Visa { .. } => Ok(()),
168170
}
169171
}

src/model/tti.rs

+2
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ impl NonBlock for Instrument {
194194
fn set_nonblocking(&mut self, enable: bool) -> crate::error::Result<()> {
195195
match &mut self.protocol {
196196
Protocol::Raw(r) => r.set_nonblocking(enable),
197+
198+
#[cfg(feature = "visa")]
197199
Protocol::Visa { .. } => Ok(()),
198200
}
199201
}

src/model/versatest.rs

+2
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,8 @@ impl NonBlock for Instrument {
196196
fn set_nonblocking(&mut self, enable: bool) -> crate::error::Result<()> {
197197
match &mut self.protocol {
198198
Protocol::Raw(r) => r.set_nonblocking(enable),
199+
200+
#[cfg(feature = "visa")]
199201
Protocol::Visa { .. } => Ok(()),
200202
}
201203
}

src/protocol.rs

+82-6
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,85 @@
11
use std::{
22
error::Error,
33
fmt::Display,
4-
io::{ErrorKind, Read, Write},
4+
io::{Read, Write},
5+
path::Path,
56
};
67

8+
#[cfg(target_os = "linux")]
9+
use std::path::PathBuff;
10+
11+
use crate::{error::Result, instrument::Info, InstrumentError, Interface};
12+
13+
#[cfg(feature = "visa")]
714
use tracing::{trace, warn};
15+
16+
#[cfg(feature = "visa")]
17+
use std::io::ErrorKind;
18+
19+
#[cfg(feature = "visa")]
20+
use crate::instrument::info::get_info;
21+
22+
#[cfg(feature = "visa")]
823
use visa_rs::{
924
enums::{assert::AssertTrigPro, status::ErrorCode},
1025
flags::{AccessMode, FlushMode},
1126
AsResourceManager, DefaultRM, VisaString, TIMEOUT_INFINITE,
1227
};
1328

14-
use crate::{
15-
error::Result,
16-
instrument::{info::get_info, Info},
17-
InstrumentError, Interface,
18-
};
29+
#[must_use]
30+
pub fn is_visa_installed() -> bool {
31+
#[cfg(all(target_os = "windows", target_arch = "x86_64"))]
32+
{
33+
let search_path =
34+
r"C:\Program Files (x86)\IVI Foundation\VISA\WinNT\Lib_x64\msc\visa64.lib";
35+
Path::new(search_path).exists()
36+
}
37+
#[cfg(target_os = "linux")]
38+
{
39+
let Some(search_paths) = std::env::var_os("LD_LIBRARY_PATH") else {
40+
return false;
41+
};
42+
let Ok(search_paths) = search_paths.into_string() else {
43+
return false;
44+
};
45+
for p in search_paths.split(":") {
46+
let Ok(dir) = Path::new(&p).read_dir() else {
47+
return false;
48+
};
49+
if dir
50+
.find(|e| {
51+
let Ok(e) = e else {
52+
return false;
53+
};
54+
let Ok(f) = e.file_name().into_string() else {
55+
return false;
56+
};
57+
58+
//parse::<PathBuf> is infallible so unwrap is ok here.
59+
let path = p.parse::<PathBuf>().unwrap().join(f);
60+
61+
path.file_stem()
62+
.unwrap()
63+
.to_string_lossy()
64+
.contains("libvisa")
65+
})
66+
.is_some()
67+
{
68+
return true;
69+
}
70+
}
71+
false
72+
}
73+
#[cfg(target_os = "macos")]
74+
{
75+
false
76+
}
77+
}
1978

2079
pub enum Protocol {
2180
Raw(Box<dyn Interface>),
81+
82+
#[cfg(feature = "visa")]
2283
Visa {
2384
instr: visa_rs::Instrument,
2485
rm: DefaultRM,
@@ -107,6 +168,8 @@ impl Read for Protocol {
107168
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
108169
match self {
109170
Self::Raw(r) => r.read(buf),
171+
172+
#[cfg(feature = "visa")]
110173
Self::Visa { instr, .. } => {
111174
let stb = Stb::Stb(instr.read_stb().map_err(|e| {
112175
std::io::Error::new(ErrorKind::Other, format!("error reading STB: {e}"))
@@ -125,13 +188,17 @@ impl Write for Protocol {
125188
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
126189
match self {
127190
Self::Raw(r) => r.write(buf),
191+
192+
#[cfg(feature = "visa")]
128193
Self::Visa { instr, .. } => instr.write(buf),
129194
}
130195
}
131196

132197
fn flush(&mut self) -> std::io::Result<()> {
133198
match self {
134199
Self::Raw(r) => r.flush(),
200+
201+
#[cfg(feature = "visa")]
135202
Self::Visa { instr, .. } => match instr.visa_flush(FlushMode::IO_OUT_BUF) {
136203
Ok(v) => Ok(v),
137204
// viFlush(instrument, VI_IO_OUT_BUF) on USB throws this error, but we
@@ -150,6 +217,8 @@ impl Info for Protocol {
150217
fn info(&mut self) -> crate::error::Result<crate::instrument::info::InstrumentInfo> {
151218
match self {
152219
Self::Raw(r) => r.info(),
220+
221+
#[cfg(feature = "visa")]
153222
Self::Visa { instr, .. } => get_info(instr),
154223
}
155224
}
@@ -160,6 +229,8 @@ impl Clear for Protocol {
160229
fn clear(&mut self) -> core::result::Result<(), Self::Error> {
161230
match self {
162231
Self::Raw(r) => r.write_all(b"*CLS")?,
232+
233+
#[cfg(feature = "visa")]
163234
Self::Visa { instr, .. } => instr.clear()?,
164235
};
165236

@@ -172,6 +243,8 @@ impl ReadStb for Protocol {
172243
fn read_stb(&mut self) -> core::result::Result<Stb, Self::Error> {
173244
match self {
174245
Self::Raw(_) => Ok(Stb::NotSupported),
246+
247+
#[cfg(feature = "visa")]
175248
Self::Visa { instr, .. } => Ok(Stb::Stb(instr.read_stb()?)),
176249
}
177250
}
@@ -184,6 +257,8 @@ impl Trigger for Protocol {
184257
Self::Raw(r) => {
185258
r.write_all(b"*TRG\n")?;
186259
}
260+
261+
#[cfg(feature = "visa")]
187262
Self::Visa { instr, .. } => {
188263
instr.assert_trigger(AssertTrigPro::TrigProtDefault)?;
189264
}
@@ -198,6 +273,7 @@ impl Protocol {
198273
///
199274
/// # Errors
200275
/// Errors may occur from the system Visa drivers.
276+
#[cfg(feature = "visa")]
201277
#[tracing::instrument]
202278
pub fn try_from_visa(visa_string: String) -> Result<Self> {
203279
trace!("Getting VISA Resource Manager");

0 commit comments

Comments
 (0)