usb_if/host/
mod.rs

1use alloc::{boxed::Box, string::String, vec::Vec};
2use futures::future::LocalBoxFuture;
3
4use crate::{
5    descriptor::{ConfigurationDescriptor, DeviceDescriptor},
6    err::TransferError,
7    transfer::{Recipient, Request, RequestType, wait::Waiter},
8};
9
10pub trait Controller: Send + 'static {
11    fn init(&mut self) -> LocalBoxFuture<'_, Result<(), USBError>>;
12    fn device_list(&self) -> LocalBoxFuture<'_, Result<Vec<Box<dyn DeviceInfo>>, USBError>>;
13
14    /// Used in interrupt context.
15    fn handle_event(&mut self);
16}
17
18pub trait DeviceInfo: Send + 'static {
19    fn open(&mut self) -> LocalBoxFuture<'_, Result<Box<dyn Device>, USBError>>;
20    fn descriptor(&self) -> LocalBoxFuture<'_, Result<DeviceDescriptor, USBError>>;
21    fn configuration_descriptor(
22        &mut self,
23        index: u8,
24    ) -> LocalBoxFuture<'_, Result<ConfigurationDescriptor, USBError>>;
25}
26
27pub trait Device: Send + 'static {
28    fn set_configuration(&mut self, configuration: u8) -> LocalBoxFuture<'_, Result<(), USBError>>;
29    fn get_configuration(&mut self) -> LocalBoxFuture<'_, Result<u8, USBError>>;
30    fn claim_interface(
31        &mut self,
32        interface: u8,
33        alternate: u8,
34    ) -> LocalBoxFuture<'_, Result<Box<dyn Interface>, USBError>>;
35
36    fn control_in<'a>(&mut self, setup: ControlSetup, data: &'a mut [u8]) -> ResultTransfer<'a>;
37    fn control_out<'a>(&mut self, setup: ControlSetup, data: &'a [u8]) -> ResultTransfer<'a>;
38}
39
40pub trait Interface: Send + 'static {
41    fn set_alt_setting(&mut self, alt_setting: u8) -> Result<(), USBError>;
42    fn get_alt_setting(&self) -> Result<u8, USBError>;
43    fn control_in<'a>(&mut self, setup: ControlSetup, data: &'a mut [u8]) -> ResultTransfer<'a>;
44    fn control_out<'a>(&mut self, setup: ControlSetup, data: &'a [u8]) -> ResultTransfer<'a>;
45    fn endpoint_bulk_in(&mut self, endpoint: u8) -> Result<Box<dyn EndpointBulkIn>, USBError>;
46    fn endpoint_bulk_out(&mut self, endpoint: u8) -> Result<Box<dyn EndpointBulkOut>, USBError>;
47    fn endpoint_interrupt_in(
48        &mut self,
49        endpoint: u8,
50    ) -> Result<Box<dyn EndpointInterruptIn>, USBError>;
51    fn endpoint_interrupt_out(
52        &mut self,
53        endpoint: u8,
54    ) -> Result<Box<dyn EndpointInterruptOut>, USBError>;
55    fn endpoint_iso_in(&mut self, endpoint: u8) -> Result<Box<dyn EndpintIsoIn>, USBError>;
56    fn endpoint_iso_out(&mut self, endpoint: u8) -> Result<Box<dyn EndpintIsoOut>, USBError>;
57}
58
59pub trait TEndpoint: Send + 'static {}
60
61pub trait EndpointBulkIn: TEndpoint {
62    fn submit<'a>(&mut self, data: &'a mut [u8]) -> ResultTransfer<'a>;
63}
64pub trait EndpointBulkOut: TEndpoint {
65    fn submit<'a>(&mut self, data: &'a [u8]) -> ResultTransfer<'a>;
66}
67
68pub trait EndpointInterruptIn: TEndpoint {
69    fn submit<'a>(&mut self, data: &'a mut [u8]) -> ResultTransfer<'a>;
70}
71
72pub trait EndpointInterruptOut: TEndpoint {
73    fn submit<'a>(&mut self, data: &'a [u8]) -> ResultTransfer<'a>;
74}
75
76pub trait EndpintIsoIn: TEndpoint {
77    fn submit<'a>(&mut self, data: &'a mut [u8], num_iso_packets: usize) -> ResultTransfer<'a>;
78}
79
80pub trait EndpintIsoOut: TEndpoint {
81    fn submit<'a>(&mut self, data: &'a [u8], num_iso_packets: usize) -> ResultTransfer<'a>;
82}
83
84// pub type BoxTransfer<'a> = Pin<Box<dyn Transfer<'a> + Send>>;
85pub type TransferFuture<'a> = Waiter<'a, Result<usize, TransferError>>;
86pub type ResultTransfer<'a> = Result<TransferFuture<'a>, TransferError>;
87
88pub trait Transfer<'a>: Future<Output = Result<usize, TransferError>> + Send + 'a {}
89
90#[derive(thiserror::Error, Debug)]
91pub enum USBError {
92    #[error("Timeout")]
93    Timeout,
94    #[error("No memory available")]
95    NoMemory,
96    #[error("Transfer error: {0}")]
97    TransferError(#[from] TransferError),
98    #[error("Not initialized")]
99    NotInitialized,
100    #[error("Not found")]
101    NotFound,
102    #[error("Slot limit reached")]
103    SlotLimitReached,
104    #[error("Configuration not set")]
105    ConfigurationNotSet,
106    #[error("Other error: {0}")]
107    Other(String),
108}
109
110impl From<Box<dyn core::error::Error>> for USBError {
111    fn from(err: Box<dyn core::error::Error>) -> Self {
112        USBError::Other(alloc::format!("{err}"))
113    }
114}
115
116#[derive(Debug, Clone)]
117pub struct ControlSetup {
118    pub request_type: RequestType,
119    pub recipient: Recipient,
120    pub request: Request,
121    pub value: u16,
122    pub index: u16,
123}