pub mod backend;
pub mod dac;
pub mod error;
pub mod protocol;
pub use crate::protocols::lasercube_usb::dac::{DeviceInfo, DeviceStatus, FirmwareVersion, Stream};
pub use crate::protocols::lasercube_usb::error::{Error, Result};
pub use crate::protocols::lasercube_usb::protocol::Sample;
pub use backend::LasercubeUsbBackend;
pub use rusb;
use crate::types::{DacCapabilities, OutputModel};
pub fn default_capabilities() -> DacCapabilities {
DacCapabilities {
pps_min: 1,
pps_max: 35_000,
max_points_per_chunk: 4096,
output_model: OutputModel::NetworkFifo,
}
}
use protocol::{LASERDOCK_PID, LASERDOCK_VID};
use rusb::UsbContext;
use std::time::Duration;
const TIMEOUT: Duration = Duration::from_millis(1000);
pub struct DacController {
context: rusb::Context,
}
impl DacController {
pub fn new() -> Result<Self> {
Ok(DacController {
context: rusb::Context::new()?,
})
}
pub fn list_devices(&self) -> Result<Vec<rusb::Device<rusb::Context>>> {
let devices = self.context.devices()?;
let mut dacs = Vec::new();
for device in devices.iter() {
let descriptor = device.device_descriptor()?;
if descriptor.vendor_id() == LASERDOCK_VID && descriptor.product_id() == LASERDOCK_PID {
dacs.push(device);
}
}
Ok(dacs)
}
pub fn open_first(&self) -> Result<dac::Stream<rusb::Context>> {
let devices = self.list_devices()?;
let device = devices.into_iter().next().ok_or(Error::DeviceNotOpened)?;
dac::Stream::open(device)
}
}
pub fn discover_dacs() -> Result<Vec<rusb::Device<rusb::Context>>> {
let controller = DacController::new()?;
controller.list_devices()
}
pub fn is_laserdock_device<T: UsbContext>(device: &rusb::Device<T>) -> bool {
device
.device_descriptor()
.is_ok_and(|d| d.vendor_id() == LASERDOCK_VID && d.product_id() == LASERDOCK_PID)
}
pub fn get_serial_number<T: UsbContext>(device: &rusb::Device<T>) -> Option<String> {
let descriptor = device.device_descriptor().ok()?;
descriptor.serial_number_string_index()?;
let handle = device.open().ok()?;
let languages = handle.read_languages(TIMEOUT).ok()?;
let lang = languages.first()?;
handle
.read_serial_number_string(*lang, &descriptor, TIMEOUT)
.ok()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_sample_creation() {
let sample = Sample::new(2048, 2048, 255, 128, 64);
assert_eq!(sample.x, 2048);
assert_eq!(sample.y, 2048);
assert_eq!(sample.red(), 255);
assert_eq!(sample.green(), 128);
assert_eq!(sample.blue(), 64);
}
#[test]
fn test_sample_blank() {
let blank = Sample::blank();
assert_eq!(blank.red(), 0);
assert_eq!(blank.green(), 0);
assert_eq!(blank.blue(), 0);
}
}