1use alloc::vec::Vec;
2use core::ptr::NonNull;
3
4use crate::{descriptor::EndpointDescriptor, host::ControlSetup};
5pub use crate::{descriptor::EndpointType, transfer::Direction};
6
7#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
8pub struct EndpointAddress(u8);
9
10impl EndpointAddress {
11 pub const CONTROL: Self = Self(0);
12
13 pub const fn new(raw: u8) -> Self {
14 Self(raw)
15 }
16
17 pub const fn raw(self) -> u8 {
18 self.0
19 }
20
21 pub fn direction(self) -> Direction {
22 Direction::from_address(self.0)
23 }
24}
25
26impl From<u8> for EndpointAddress {
27 fn from(value: u8) -> Self {
28 Self::new(value)
29 }
30}
31
32impl From<EndpointAddress> for u8 {
33 fn from(value: EndpointAddress) -> Self {
34 value.raw()
35 }
36}
37
38#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
39pub struct RequestId(u64);
40
41impl RequestId {
42 pub const fn new(raw: u64) -> Self {
43 Self(raw)
44 }
45
46 pub const fn raw(self) -> u64 {
47 self.0
48 }
49}
50
51#[derive(Clone, Copy, Debug, PartialEq, Eq)]
52pub struct EndpointInfo {
53 pub address: EndpointAddress,
54 pub transfer_type: EndpointType,
55 pub direction: Direction,
56 pub max_packet_size: u16,
57 pub packets_per_microframe: usize,
58 pub interval: u8,
59}
60
61impl EndpointInfo {
62 pub const fn control() -> Self {
63 Self {
64 address: EndpointAddress::CONTROL,
65 transfer_type: EndpointType::Control,
66 direction: Direction::Out,
67 max_packet_size: 64,
68 packets_per_microframe: 1,
69 interval: 0,
70 }
71 }
72}
73
74impl From<&EndpointDescriptor> for EndpointInfo {
75 fn from(desc: &EndpointDescriptor) -> Self {
76 Self {
77 address: EndpointAddress::new(desc.address),
78 transfer_type: desc.transfer_type,
79 direction: desc.direction,
80 max_packet_size: desc.max_packet_size,
81 packets_per_microframe: desc.packets_per_microframe,
82 interval: desc.interval,
83 }
84 }
85}
86
87#[derive(Clone, Copy)]
88pub struct TransferBuffer {
89 pub ptr: NonNull<u8>,
90 pub len: usize,
91}
92
93unsafe impl Send for TransferBuffer {}
94unsafe impl Sync for TransferBuffer {}
95
96impl TransferBuffer {
97 pub fn from_mut_slice(slice: &mut [u8]) -> Option<Self> {
98 NonNull::new(slice.as_mut_ptr()).map(|ptr| Self {
99 ptr,
100 len: slice.len(),
101 })
102 }
103
104 pub fn from_slice(slice: &[u8]) -> Option<Self> {
105 NonNull::new(slice.as_ptr() as *mut u8).map(|ptr| Self {
106 ptr,
107 len: slice.len(),
108 })
109 }
110}
111
112#[derive(Clone)]
113pub enum TransferKind {
114 Control(ControlSetup),
115 Bulk,
116 Interrupt,
117 Isochronous { packet_lengths: Vec<usize> },
118}
119
120impl TransferKind {
121 pub fn get_control(&self) -> Option<&ControlSetup> {
122 match self {
123 TransferKind::Control(setup) => Some(setup),
124 _ => None,
125 }
126 }
127
128 pub fn iso_packet_lengths(&self) -> Option<&[usize]> {
129 match self {
130 TransferKind::Isochronous { packet_lengths } => Some(packet_lengths),
131 _ => None,
132 }
133 }
134}
135
136#[derive(Clone, Copy, Debug, PartialEq, Eq)]
137pub struct IsoPacketRequest {
138 pub length: usize,
139}
140
141#[derive(Clone)]
142pub enum TransferRequest {
143 Control {
144 setup: ControlSetup,
145 direction: Direction,
146 buffer: Option<TransferBuffer>,
147 },
148 Bulk {
149 direction: Direction,
150 buffer: Option<TransferBuffer>,
151 },
152 Interrupt {
153 direction: Direction,
154 buffer: Option<TransferBuffer>,
155 },
156 Isochronous {
157 direction: Direction,
158 buffer: Option<TransferBuffer>,
159 packets: Vec<IsoPacketRequest>,
160 },
161}
162
163impl TransferRequest {
164 pub fn control_in(setup: ControlSetup, buffer: &mut [u8]) -> Self {
165 Self::Control {
166 setup,
167 direction: Direction::In,
168 buffer: TransferBuffer::from_mut_slice(buffer),
169 }
170 }
171
172 pub fn control_out(setup: ControlSetup, buffer: &[u8]) -> Self {
173 Self::Control {
174 setup,
175 direction: Direction::Out,
176 buffer: TransferBuffer::from_slice(buffer),
177 }
178 }
179
180 pub fn bulk_in(buffer: &mut [u8]) -> Self {
181 Self::Bulk {
182 direction: Direction::In,
183 buffer: TransferBuffer::from_mut_slice(buffer),
184 }
185 }
186
187 pub fn bulk_out(buffer: &[u8]) -> Self {
188 Self::Bulk {
189 direction: Direction::Out,
190 buffer: TransferBuffer::from_slice(buffer),
191 }
192 }
193
194 pub fn interrupt_in(buffer: &mut [u8]) -> Self {
195 Self::Interrupt {
196 direction: Direction::In,
197 buffer: TransferBuffer::from_mut_slice(buffer),
198 }
199 }
200
201 pub fn interrupt_out(buffer: &[u8]) -> Self {
202 Self::Interrupt {
203 direction: Direction::Out,
204 buffer: TransferBuffer::from_slice(buffer),
205 }
206 }
207
208 pub fn iso_in(buffer: &mut [u8], packet_lengths: &[usize]) -> Self {
209 Self::Isochronous {
210 direction: Direction::In,
211 buffer: TransferBuffer::from_mut_slice(buffer),
212 packets: packet_lengths
213 .iter()
214 .copied()
215 .map(|length| IsoPacketRequest { length })
216 .collect(),
217 }
218 }
219
220 pub fn iso_out(buffer: &[u8], packet_lengths: &[usize]) -> Self {
221 Self::Isochronous {
222 direction: Direction::Out,
223 buffer: TransferBuffer::from_slice(buffer),
224 packets: packet_lengths
225 .iter()
226 .copied()
227 .map(|length| IsoPacketRequest { length })
228 .collect(),
229 }
230 }
231
232 pub fn direction(&self) -> Direction {
233 match self {
234 Self::Control { direction, .. }
235 | Self::Bulk { direction, .. }
236 | Self::Interrupt { direction, .. }
237 | Self::Isochronous { direction, .. } => *direction,
238 }
239 }
240
241 pub fn buffer(&self) -> Option<TransferBuffer> {
242 match self {
243 Self::Control { buffer, .. }
244 | Self::Bulk { buffer, .. }
245 | Self::Interrupt { buffer, .. }
246 | Self::Isochronous { buffer, .. } => *buffer,
247 }
248 }
249
250 pub fn iso_packets(&self) -> &[IsoPacketRequest] {
251 match self {
252 Self::Isochronous { packets, .. } => packets,
253 _ => &[],
254 }
255 }
256}
257
258impl From<TransferRequest> for (TransferKind, Direction, Option<TransferBuffer>) {
259 fn from(request: TransferRequest) -> Self {
260 match request {
261 TransferRequest::Control {
262 setup,
263 direction,
264 buffer,
265 } => (TransferKind::Control(setup), direction, buffer),
266 TransferRequest::Bulk { direction, buffer } => (TransferKind::Bulk, direction, buffer),
267 TransferRequest::Interrupt { direction, buffer } => {
268 (TransferKind::Interrupt, direction, buffer)
269 }
270 TransferRequest::Isochronous {
271 direction,
272 buffer,
273 packets,
274 } => (
275 TransferKind::Isochronous {
276 packet_lengths: packets.into_iter().map(|packet| packet.length).collect(),
277 },
278 direction,
279 buffer,
280 ),
281 }
282 }
283}
284
285impl From<(TransferKind, Direction, Option<TransferBuffer>)> for TransferRequest {
286 fn from((kind, direction, buffer): (TransferKind, Direction, Option<TransferBuffer>)) -> Self {
287 match kind {
288 TransferKind::Control(setup) => Self::Control {
289 setup,
290 direction,
291 buffer,
292 },
293 TransferKind::Bulk => Self::Bulk { direction, buffer },
294 TransferKind::Interrupt => Self::Interrupt { direction, buffer },
295 TransferKind::Isochronous { packet_lengths } => Self::Isochronous {
296 direction,
297 buffer,
298 packets: packet_lengths
299 .into_iter()
300 .map(|length| IsoPacketRequest { length })
301 .collect(),
302 },
303 }
304 }
305}
306
307#[derive(Clone, Copy, Debug, PartialEq, Eq)]
308pub enum TransferStatus {
309 Completed,
310 Stalled,
311 Cancelled,
312 Error,
313}
314
315#[derive(Clone, Copy, Debug, PartialEq, Eq)]
316pub struct IsoPacketResult {
317 pub requested_length: usize,
318 pub actual_length: usize,
319 pub status: TransferStatus,
320}
321
322#[derive(Clone, Debug)]
323pub struct TransferCompletion {
324 pub request_id: RequestId,
325 pub status: TransferStatus,
326 pub actual_length: usize,
327 pub iso_packets: Vec<IsoPacketResult>,
328}