crab_usb/backend/ty/ep/
mod.rs1use 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}