A thin wrapper around the MultiHarp control library
for Rust. Provides a DebugMultiHarp150 struct to
emulate the behavior of a MultiHarp without actually
being connected to one. Provides a few additional convenience
functions, such as a Config struct to set many parameters
in one call.
-
Make the debug simulation more complete than it currently is.
-
Implement FPGA functionality / MultiHarp 160
-
Benchmarking and test suites.
-
async
Not all functions are available on all MHLib versions.
Use the features flags to build for your installed driver.
If you are unsure which library you are using, install with the
MHLib flag, then use the get_library_version() function to
check.
-
nolib- for use on machines that have no installed MultiHarp library, just for debugging (e.g. if you are working on an application that reads from a MultiHarp but on a system without one connected) TheCAPI is not exposed by thisPatinabut only theDebugMultiHarpstructs will be built. -
default- the default flags for this library, which presume a user is usingMHLib >=v3.0(uses flagsMHLibandMHLv3_0_0) -
MHLib- A flag forMHLib <3functionality only -
MHLv3_0_0- A flag for features compliant withv3.0.0but no further -
MHLv3_1_0- BuildsMHLibv3_0_0functionality + functions specific tov3.1.0
Warning! Not all functionality has been tested yet. The current developer does not use the White Rabbit and FPGA functionality, and has not tested the event filtering. Use at your own risk (and then send feedback to [email protected])!
This library wraps the C API and provides Rust-style
access to the functionality. For example code, refer to
the source code in src/bin. This section provides only
a very minimal example.
use multi_harp_patina::*;
fn main(){
// This line opens the first `MultiHarp150` it finds,
// handling the various errors with a print line and
// terminating the code without a panic.
let multi_harp = open_first_device::<MultiHarp150>();
match &multi_harp {
Ok(m) => {
println!("Opened device with serial number {}", m.get_serial());
}
Err(e) => {
match e {
PatinaError::NoDeviceAvailable => println!("No devices available"),
PatinaError::ArgumentError(s, i, msg) => println!("Argument error: {} {} {}", s, i, msg),
PatinaError::MultiHarpError(e) => println!("Error opening device: {:?}", e),
_ => println!("Unknown error opening device"),
}
return ();
}
}
let mut mh = multi_harp.unwrap();
mh.init(MeasurementMode::T3, ReferenceClock::Internal)
.map_err(|e| {println!("Error initializing device: {:?}", e); return ();})
.unwrap();
// Run for 4 seconds
mh.start_measurement(4000)
.map_err(|e| {
println!("Error starting measurement: {:?}", e); return ();
}).unwrap();
// Normally you'd handle this stuff with multi-threading,
// allowing the buffer to be read and processed in parallel
// for maximum efficiency. Check out the examples!
let mut buf = vec![0u32; multi_harp_patina::TTREADMAX];
while let Ok(x) = mh.ctc_status() {
if !x {break;}
let n_reads = mh.read_fifo(&mut buf)
.map_err(|e| {
println!("Error reading FIFO: {:?}", e); return ();
}).unwrap();
// Do something with the data,
// send it to another thread,
// send it to a friend,
// write it to a file??
/* - snip - */
}
mh.stop_measurement().map_err(|e| {
println!("Error stopping measurement: {:?}", e); return ();
}).unwrap();
// when mh goes out of scope, it will call `CloseDevice` on its
// own
}