vlfd_rs/
lib.rs

1//! # vlfd-rs
2//!
3//! Rust bindings for the SMIMS VLFD board. The crate exposes two high-level
4//! entry points: [`Device`] for day-to-day interaction with VeriComm I/O and
5//! [`Programmer`] for uploading FPGA bitstreams. The following example opens
6//! the device, switches to VeriComm mode, and performs a single FIFO
7//! transaction:
8//!
9//! ```no_run
10//! use vlfd_rs::{Device, IoSettings, Result};
11//!
12//! fn main() -> Result<()> {
13//!     // Establish a connection and load the remote configuration/encryption tables.
14//!     let mut device = Device::connect()?;
15//!
16//!     // Override default VeriComm timing before entering I/O mode.
17//!     let mut settings = IoSettings::default();
18//!     settings.clock_high_delay = 8;
19//!     settings.clock_low_delay = 8;
20//!     device.enter_io_mode(&settings)?;
21//!
22//!     // Perform a 4-word FIFO round-trip with transparent encryption.
23//!     let mut tx = [0x1234u16, 0x5678, 0x9abc, 0xdef0];
24//!     let mut rx = [0u16; 4];
25//!     device.transfer_io(&mut tx, &mut rx)?;
26//!
27//!     device.exit_io_mode()?;
28//!     Ok(())
29//! }
30//! ```
31//!
32//! To reprogram the FPGA, construct a [`Programmer`]:
33//!
34//! ```no_run
35//! use std::path::Path;
36//! use vlfd_rs::{Programmer, Result};
37//!
38//! fn main() -> Result<()> {
39//!     let mut programmer = Programmer::connect()?;
40//!     programmer.program(Path::new("path/to/bitstream.txt"))?;
41//!     programmer.close()?;
42//!     Ok(())
43//! }
44//! ```
45//!
46//! Both examples are tagged with `no_run`, so they compile during `cargo test`
47//! but do not touch live hardware.
48pub mod constants;
49
50mod config;
51mod device;
52mod error;
53mod program;
54mod usb;
55
56pub use config::Config;
57pub use device::{Device, IoSettings};
58pub use error::{Error, Result};
59pub use program::Programmer;
60pub use usb::{HotplugEvent, HotplugEventKind, HotplugOptions, HotplugRegistration};
61
62#[cfg(test)]
63mod tests {
64    use super::*;
65
66    #[test]
67    fn device_is_created_closed() {
68        let device = Device::new().expect("failed to initialise USB context");
69        assert!(!device.is_open());
70    }
71
72    #[test]
73    fn config_mutation_roundtrip() {
74        let mut device = Device::new().expect("failed to initialise USB context");
75        device.config_mut().set_vericomm_clock_high_delay(42);
76        assert_eq!(device.config().vericomm_clock_high_delay(), 42);
77    }
78
79    #[test]
80    fn programmer_wraps_device() {
81        let device = Device::new().expect("failed to initialise USB context");
82        let programmer = Programmer::new(device);
83        assert!(!programmer.device().is_open());
84    }
85}