Skip to main content

crab_usb/backend/ty/ep/
mod.rs

1use alloc::boxed::Box;
2use core::any::Any;
3use core::ptr::NonNull;
4use core::{
5    future::Future,
6    pin::Pin,
7    task::{Context, Poll},
8};
9use usb_if::transfer::Direction;
10
11use crate::backend::ty::transfer::TransferKind;
12
13use super::transfer::Transfer;
14use usb_if::err::TransferError;
15
16mod bulk;
17mod ctrl;
18mod int;
19mod iso;
20
21pub use bulk::*;
22pub use ctrl::*;
23pub use int::*;
24pub use iso::*;
25
26pub enum EndpointKind {
27    Control(EndpointControl),
28    IsochronousIn(EndpointIsoIn),
29    IsochronousOut(EndpointIsoOut),
30    BulkIn(EndpointBulkIn),
31    BulkOut(EndpointBulkOut),
32    InterruptIn(EndpointInterruptIn),
33    InterruptOut(EndpointInterruptOut),
34}
35
36pub(crate) struct EndpointBase {
37    raw: Box<dyn EndpointOp>,
38}
39
40impl EndpointBase {
41    pub fn new(raw: impl EndpointOp) -> Self {
42        Self { raw: Box::new(raw) }
43    }
44
45    pub fn new_transfer(
46        &mut self,
47        kind: TransferKind,
48        direction: Direction,
49        buff: Option<(NonNull<u8>, usize)>,
50    ) -> Transfer {
51        self.raw.new_transfer(kind, direction, buff)
52    }
53
54    pub fn submit_and_wait(
55        &mut self,
56        transfer: Transfer,
57    ) -> impl Future<Output = Result<Transfer, TransferError>> {
58        let handle = self.submit(transfer);
59        async move {
60            let handle = handle?;
61            handle.await
62        }
63    }
64
65    pub fn submit(&mut self, transfer: Transfer) -> Result<TransferHandle<'_>, TransferError> {
66        self.raw.submit(transfer)
67    }
68
69    #[allow(unused)]
70    pub(crate) fn as_raw_mut<T: EndpointOp>(&mut self) -> &mut T {
71        let d = self.raw.as_mut() as &mut dyn Any;
72        d.downcast_mut::<T>()
73            .expect("EndpointBase downcast_mut failed")
74    }
75}
76
77pub(crate) trait EndpointOp: Send + Any + 'static {
78    fn new_transfer(
79        &mut self,
80        kind: TransferKind,
81        direction: Direction,
82        buff: Option<(NonNull<u8>, usize)>,
83    ) -> Transfer;
84
85    fn submit(&mut self, transfer: Transfer) -> Result<TransferHandle<'_>, TransferError>;
86
87    fn query_transfer(&mut self, id: u64) -> Option<Result<Transfer, TransferError>>;
88
89    fn register_cx(&self, id: u64, cx: &mut Context<'_>);
90}
91
92pub struct TransferHandle<'a> {
93    pub(crate) id: u64,
94    pub(crate) endpoint: &'a mut dyn EndpointOp,
95}
96
97impl<'a> TransferHandle<'a> {
98    pub(crate) fn new(id: u64, endpoint: &'a mut dyn EndpointOp) -> Self {
99        Self { id, endpoint }
100    }
101}
102
103impl<'a> Future for TransferHandle<'a> {
104    type Output = Result<Transfer, TransferError>;
105
106    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
107        let id = self.id;
108        match self.endpoint.query_transfer(id) {
109            Some(res) => Poll::Ready(res),
110            None => {
111                self.endpoint.register_cx(id, cx);
112                Poll::Pending
113            }
114        }
115    }
116}