summaryrefslogtreecommitdiff
path: root/src/usb/mod.rs
diff options
context:
space:
mode:
authorDawid Rycerz <dawid@rycerz.xyz>2026-02-08 12:44:10 +0100
committerDawid Rycerz <dawid@rycerz.xyz>2026-02-08 12:44:10 +0100
commit0c20fb86633104744dbccf30ad732296694fff1b (patch)
tree02ffb8494086960b4a84decf3bdc2c8c61bfc4f6 /src/usb/mod.rs
Initial pipewiremain
Diffstat (limited to 'src/usb/mod.rs')
-rw-r--r--src/usb/mod.rs164
1 files changed, 164 insertions, 0 deletions
diff --git a/src/usb/mod.rs b/src/usb/mod.rs
new file mode 100644
index 0000000..38d9c7d
--- /dev/null
+++ b/src/usb/mod.rs
@@ -0,0 +1,164 @@
+//! 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<String>,
+ pub product: Option<String>,
+ pub serial_number: Option<String>,
+}
+
+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<UsbEndpoint>,
+}
+
+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<UsbInterface>,
+ 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);
+ }
+}