neuromorphic_drivers/
device.rs

1use crate::flag;
2use crate::usb;
3use rusb::UsbContext;
4
5#[derive(Debug, Clone)]
6pub struct ListedDevice {
7    pub bus_number: u8,
8    pub address: u8,
9    pub speed: usb::Speed,
10    pub serial: Result<String, usb::Error>,
11}
12
13#[derive(Debug, Clone, Copy)]
14pub struct TemperatureCelsius(pub f32);
15
16pub type HandleAndProperties = (rusb::DeviceHandle<rusb::Context>, (u16, u16), String);
17
18#[derive(Debug, Clone, Copy)]
19pub enum SerialOrBusNumberAndAddress<'a> {
20    Serial(&'a str),
21    BusNumberAndAddress((u8, u8)),
22    None,
23}
24
25pub trait Usb: Sized {
26    type Adapter;
27    type Configuration;
28    type Error;
29    type Properties;
30
31    const VENDOR_AND_PRODUCT_IDS: &'static [(u16, u16)];
32
33    const PROPERTIES: Self::Properties;
34
35    const DEFAULT_USB_CONFIGURATION: usb::Configuration;
36
37    /// read_serial must return Ok(None) if the device is not compatible with the interface.
38    /// This behaviour is required to support Prophesee EVK3 HD cameras, which share a VID/PID with
39    /// EVK4 cameras.
40    ///
41    /// read_serial must claim bulk transfer interface(s).
42    ///
43    /// This is required even if read_serial does not use bulk transfers.
44    fn read_serial(handle: &mut rusb::DeviceHandle<rusb::Context>) -> rusb::Result<Option<String>>;
45
46    fn default_configuration(&self) -> Self::Configuration;
47
48    fn current_configuration(&self) -> Self::Configuration;
49
50    fn update_configuration(&self, configuration: Self::Configuration);
51
52    fn open<IntoError, IntoWarning>(
53        serial_or_bus_number_and_address: SerialOrBusNumberAndAddress,
54        configuration: Self::Configuration,
55        usb_configuration: &usb::Configuration,
56        event_loop: std::sync::Arc<usb::EventLoop>,
57        flag: flag::Flag<IntoError, IntoWarning>,
58    ) -> Result<Self, Self::Error>
59    where
60        IntoError: From<Self::Error> + Clone + Send + 'static,
61        IntoWarning: From<crate::usb::Overflow> + Clone + Send + 'static;
62
63    fn next_with_timeout(&self, timeout: &std::time::Duration) -> Option<usb::BufferView>;
64
65    fn backlog(&self) -> usize;
66
67    fn clutch(&self) -> usb::Clutch;
68
69    fn vendor_and_product_id(&self) -> (u16, u16);
70
71    fn serial(&self) -> String;
72
73    fn chip_firmware_configuration(&self) -> Self::Configuration;
74
75    fn bus_number(&self) -> u8;
76
77    fn address(&self) -> u8;
78
79    fn speed(&self) -> usb::Speed;
80
81    fn create_adapter(&self) -> Self::Adapter;
82
83    fn list_devices(devices: &rusb::DeviceList<rusb::Context>) -> rusb::Result<Vec<ListedDevice>> {
84        let mut result = Vec::new();
85        for device in devices
86            .iter()
87            .filter(|device| match device.device_descriptor() {
88                Ok(descriptor) => {
89                    let device_vendor_and_product_id =
90                        (descriptor.vendor_id(), descriptor.product_id());
91                    Self::VENDOR_AND_PRODUCT_IDS
92                        .iter()
93                        .any(|vendor_and_product_id| {
94                            device_vendor_and_product_id == *vendor_and_product_id
95                        })
96                }
97                Err(_) => false,
98            })
99        {
100            if let Some(serial) = Self::read_serial(&mut device.open()?).transpose() {
101                result.push(ListedDevice {
102                    bus_number: device.bus_number(),
103                    address: device.address(),
104                    speed: device.speed().into(),
105                    serial: serial.map_err(|error| error.into()),
106                });
107            }
108        }
109        Ok(result)
110    }
111
112    fn open_any(context: &rusb::Context) -> Result<HandleAndProperties, usb::Error> {
113        match context.devices()?.iter().find_map(
114            |device| -> Option<rusb::Result<HandleAndProperties>> {
115                match device.device_descriptor() {
116                    Ok(descriptor) => {
117                        let device_vendor_and_product_id =
118                            (descriptor.vendor_id(), descriptor.product_id());
119                        if Self::VENDOR_AND_PRODUCT_IDS
120                            .iter()
121                            .any(|vendor_and_product_id| {
122                                device_vendor_and_product_id == *vendor_and_product_id
123                            })
124                        {
125                            let mut handle = match device.open() {
126                                Ok(handle) => handle,
127                                Err(error) => return Some(Err(error)),
128                            };
129                            let device_serial = match Self::read_serial(&mut handle) {
130                                Ok(Some(serial)) => serial,
131                                Ok(None) => return None, // ignore unsupported devices
132                                Err(_) => return None, // do not raise an error if the device is already open
133                            };
134                            let _ = handle.set_auto_detach_kernel_driver(true);
135                            Some(Ok((handle, device_vendor_and_product_id, device_serial)))
136                        } else {
137                            None
138                        }
139                    }
140                    Err(_) => None,
141                }
142            },
143        ) {
144            Some(result) => Ok(result?),
145            None => Err(usb::Error::Device),
146        }
147    }
148
149    fn open_serial(
150        context: &rusb::Context,
151        serial: &str,
152    ) -> Result<HandleAndProperties, usb::Error> {
153        match context.devices()?.iter().find_map(
154            |device| -> Option<rusb::Result<HandleAndProperties>> {
155                match device.device_descriptor() {
156                    Ok(descriptor) => {
157                        let device_vendor_and_product_id =
158                            (descriptor.vendor_id(), descriptor.product_id());
159                        if Self::VENDOR_AND_PRODUCT_IDS
160                            .iter()
161                            .any(|vendor_and_product_id| {
162                                device_vendor_and_product_id == *vendor_and_product_id
163                            })
164                        {
165                            let mut handle = match device.open() {
166                                Ok(handle) => handle,
167                                Err(error) => return Some(Err(error)),
168                            };
169                            let device_serial = match Self::read_serial(&mut handle) {
170                                Ok(Some(serial)) => serial,
171                                Ok(None) => return None, // ignore unsupported devices
172                                Err(_) => return None, // do not raise an error if the device is already open
173                            };
174                            if *serial == device_serial {
175                                let _ = handle.set_auto_detach_kernel_driver(true);
176                                Some(Ok((handle, device_vendor_and_product_id, device_serial)))
177                            } else {
178                                None
179                            }
180                        } else {
181                            None
182                        }
183                    }
184                    Err(_) => None,
185                }
186            },
187        ) {
188            Some(result) => Ok(result?),
189            None => Err(usb::Error::Serial((*serial).to_owned())),
190        }
191    }
192
193    fn open_bus_number_and_address(
194        context: &rusb::Context,
195        bus_number: u8,
196        address: u8,
197    ) -> Result<HandleAndProperties, usb::Error> {
198        match context.devices()?.iter().find_map(
199            |device| -> Option<Result<HandleAndProperties, usb::Error>> {
200                if device.bus_number() == bus_number && device.address() == address {
201                    Some(match device.device_descriptor() {
202                        Ok(descriptor) => {
203                            let device_vendor_and_product_id =
204                                (descriptor.vendor_id(), descriptor.product_id());
205                            if Self::VENDOR_AND_PRODUCT_IDS
206                                .iter()
207                                .any(|vendor_and_product_id| {
208                                    device_vendor_and_product_id == *vendor_and_product_id
209                                })
210                            {
211                                let mut handle = match device.open() {
212                                    Ok(handle) => handle,
213                                    Err(error) => return Some(Err(error.into())),
214                                };
215                                match Self::read_serial(&mut handle) {
216                                    Ok(Some(serial)) => {
217                                        let _ = handle.set_auto_detach_kernel_driver(true);
218                                        Ok((handle, device_vendor_and_product_id, serial))
219                                    }
220                                    Ok(None) => {
221                                        Err(usb::Error::BusNumberAndAddressUnsupportedDevice {
222                                            bus_number,
223                                            address,
224                                        })
225                                    }
226                                    Err(error) => Err(usb::Error::BusNumberAndAddressAccessError {
227                                        bus_number,
228                                        address,
229                                        error,
230                                    }),
231                                }
232                            } else {
233                                Err(usb::Error::BusNumberAndAddressUnexpectedIds {
234                                    bus_number,
235                                    address,
236                                    vendor_id: device_vendor_and_product_id.0,
237                                    product_id: device_vendor_and_product_id.1,
238                                })
239                            }
240                        }
241                        Err(error) => Err(usb::Error::BusNumberAndAddressAccessError {
242                            bus_number,
243                            address,
244                            error,
245                        }),
246                    })
247                } else {
248                    None
249                }
250            },
251        ) {
252            Some(result) => Ok(result?),
253            None => Err(usb::Error::BusNumberAndAddressNotFound {
254                bus_number,
255                address,
256            }),
257        }
258    }
259}