1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//! Endpoint descriptors
use crate::{desc, Endpoint};
/// Endpoint descriptor
pub struct Descriptor {
// pub bLength: u8,
// pub bDescriptorType: u8,
/// Endpoint address
pub bEndpointAddress: Endpoint,
/// Endpoint type
pub ty: Type,
/// Maximum packet size (must be less than `1 << 11`)
pub max_packet_size: u16,
/// Polling interval
pub bInterval: u8,
}
/// End point type
#[derive(Clone, Copy)]
pub enum Type {
/// Bulk endpoint
Bulk,
/// Control endpoint
Control,
/// Interrupt endpoint
Interrupt {
/// Transactions per microframe
transactions_per_microframe: Transactions,
},
/// Isochronous endpoint
Isochronous {
/// Synchronization type
synchronization_type: SynchronizationType,
/// Usage type
usage_type: UsageType,
/// Transactions per microframe
transactions_per_microframe: Transactions,
},
}
impl Type {
fn bmAttributes(&self) -> u8 {
match self {
Type::Bulk => 0b10,
Type::Control => 0b00,
Type::Interrupt { .. } => 0b11,
Type::Isochronous {
synchronization_type,
usage_type,
..
} => 0b01 | (*synchronization_type as u8) << 2 | (*usage_type as u8) << 4,
}
}
}
/// Synchronization type
#[derive(Clone, Copy)]
pub enum SynchronizationType {
/// No synchronization
NoSynchronization = 0b00,
/// Asynchronous
Asynchronous = 0b01,
/// Adaptive
Adaptive = 0b10,
/// Synchronous
Synchronous = 0b11,
}
/// Usage type
#[derive(Clone, Copy)]
pub enum UsageType {
/// Data endpoint
DataEndpoint = 0b00,
/// Feedback endpoint
FeedbackEndpoint = 0b01,
/// Implicit feedback data endpoint
ImplicitFeedbackDataEndpoint = 0b10,
}
/// Transactions per microframe
#[derive(Clone, Copy)]
pub enum Transactions {
/// 1 transaction per microframe
_1 = 0b00,
/// 2 transactions per microframe
_2 = 0b01,
/// 3 transactions per microframe
_3 = 0b10,
}
impl Descriptor {
/// The size of this descriptor on the wire
pub const SIZE: u8 = 7;
/// Returns the wire representation of this descriptor
pub fn bytes(&self) -> [u8; Self::SIZE as usize] {
let mut word = self.max_packet_size & ((1 << 11) - 1);
match self.ty {
Type::Interrupt {
transactions_per_microframe,
}
| Type::Isochronous {
transactions_per_microframe,
..
} => {
word |= (transactions_per_microframe as u16) << 11;
}
_ => {}
}
[
Self::SIZE,
desc::Type::Endpoint as u8,
self.bEndpointAddress.byte(),
self.ty.bmAttributes(),
word as u8,
(word >> 8) as u8,
self.bInterval,
]
}
}