//! USB communication module for the Geek szitman supercamera mod device; mod transfer; pub use device::UsbSupercamera; pub use transfer::{UsbTransferConfig, UsbTransferError, UsbTransferResult, UsbTransferStats}; use rusb::{Direction, TransferType}; use std::time::Duration; /// USB device constants pub const USB_VENDOR_ID: u16 = 0x2ce3; pub const USB_PRODUCT_ID: u16 = 0x3828; pub const INTERFACE_A_NUMBER: u8 = 0; pub const INTERFACE_B_NUMBER: u8 = 1; pub const INTERFACE_B_ALTERNATE_SETTING: u8 = 1; pub const ENDPOINT_1: u8 = 1; pub const ENDPOINT_2: u8 = 2; pub const USB_TIMEOUT: Duration = Duration::from_millis(1000); /// USB device information #[derive(Debug, Clone)] pub struct UsbDeviceInfo { pub vendor_id: u16, pub product_id: u16, pub manufacturer: Option, pub product: Option, pub serial_number: Option, } impl Default for UsbDeviceInfo { fn default() -> Self { Self { vendor_id: USB_VENDOR_ID, product_id: USB_PRODUCT_ID, manufacturer: None, product: None, serial_number: None, } } } /// USB endpoint configuration #[derive(Debug, Clone)] pub struct UsbEndpoint { pub address: u8, pub direction: Direction, pub transfer_type: TransferType, pub max_packet_size: u16, } impl UsbEndpoint { /// Create a new USB endpoint pub fn new( address: u8, direction: Direction, transfer_type: TransferType, max_packet_size: u16, ) -> Self { Self { address, direction, transfer_type, max_packet_size, } } } /// USB interface configuration #[derive(Debug, Clone)] pub struct UsbInterface { pub number: u8, pub alternate_setting: u8, pub endpoints: Vec, } impl UsbInterface { /// Create a new USB interface pub fn new(number: u8, alternate_setting: u8) -> Self { Self { number, alternate_setting, endpoints: Vec::new(), } } /// Add an endpoint to this interface pub fn add_endpoint(&mut self, endpoint: UsbEndpoint) { self.endpoints.push(endpoint); } } /// USB device configuration #[derive(Debug, Clone)] pub struct UsbConfig { pub interfaces: Vec, pub max_packet_size: u16, } impl Default for UsbConfig { fn default() -> Self { let mut interface_a = UsbInterface::new(INTERFACE_A_NUMBER, 0); interface_a.add_endpoint(UsbEndpoint::new( ENDPOINT_1, Direction::In, TransferType::Bulk, 0x1000, )); let mut interface_b = UsbInterface::new(INTERFACE_B_NUMBER, INTERFACE_B_ALTERNATE_SETTING); interface_b.add_endpoint(UsbEndpoint::new( ENDPOINT_2, Direction::Out, TransferType::Bulk, 64, )); Self { interfaces: vec![interface_a, interface_b], max_packet_size: 0x1000, } } } #[cfg(test)] mod tests { use super::*; #[test] fn test_usb_device_info_default() { let info = UsbDeviceInfo::default(); assert_eq!(info.vendor_id, USB_VENDOR_ID); assert_eq!(info.product_id, USB_PRODUCT_ID); } #[test] fn test_usb_endpoint_creation() { let endpoint = UsbEndpoint::new(ENDPOINT_1, Direction::In, TransferType::Bulk, 0x1000); assert_eq!(endpoint.address, ENDPOINT_1); assert_eq!(endpoint.direction, Direction::In); assert_eq!(endpoint.transfer_type, TransferType::Bulk); assert_eq!(endpoint.max_packet_size, 0x1000); } #[test] fn test_usb_interface_management() { let mut interface = UsbInterface::new(0, 0); let endpoint = UsbEndpoint::new(1, Direction::In, TransferType::Bulk, 64); interface.add_endpoint(endpoint); assert_eq!(interface.endpoints.len(), 1); assert_eq!(interface.endpoints[0].address, 1); } #[test] fn test_usb_config_default() { let config = UsbConfig::default(); assert_eq!(config.interfaces.len(), 2); assert_eq!(config.interfaces[0].number, INTERFACE_A_NUMBER); assert_eq!(config.interfaces[1].number, INTERFACE_B_NUMBER); assert_eq!(config.max_packet_size, 0x1000); } }