1
+ use :: Result ;
2
+
3
+ pub trait UsbBus {
4
+ fn enable ( & self ) ;
5
+ fn reset ( & self ) ;
6
+ fn configure_ep ( & self , ep_addr : u8 , ep_type : EndpointType , max_packet_size : u16 ) -> Result < ( ) > ;
7
+ fn set_device_address ( & self , addr : u8 ) ;
8
+ fn write ( & self , ep_addr : u8 , buf : & [ u8 ] ) -> Result < usize > ;
9
+ fn read ( & self , ep_addr : u8 , buf : & mut [ u8 ] ) -> Result < usize > ;
10
+ fn stall ( & self , ep_addr : u8 ) ;
11
+ fn unstall ( & self , ep_addr : u8 ) ;
12
+ fn poll ( & self ) -> PollResult ;
13
+ }
14
+
15
+ #[ repr( u8 ) ]
16
+ #[ derive( Copy , Clone , Debug ) ]
17
+ pub enum EndpointType {
18
+ Control = 0b00 ,
19
+ Isochronous = 0b01 ,
20
+ Bulk = 0b10 ,
21
+ Interrupt = 0b11 ,
22
+ }
23
+
24
+ // bEndpointAddress:
25
+ // D7: Direction 0 = OUT, 1 = IN
26
+
27
+ pub struct EndpointPair < ' a , B : ' a + UsbBus > {
28
+ bus : & ' a B ,
29
+ address : u8 ,
30
+ }
31
+
32
+ impl < ' a , B : UsbBus > EndpointPair < ' a , B > {
33
+ pub fn new ( bus : & ' a B , address : u8 ) -> EndpointPair < ' a , B > {
34
+ EndpointPair { bus, address }
35
+ }
36
+
37
+ pub fn split ( self , ep_type : EndpointType , max_packet_size : u16 ) -> ( EndpointOut < ' a , B > , EndpointIn < ' a , B > ) {
38
+ let ep_out = EndpointOut {
39
+ bus : self . bus ,
40
+ address : self . address ,
41
+ ep_type : ep_type,
42
+ max_packet_size,
43
+ interval : 1 ,
44
+ } ;
45
+
46
+ let ep_in = EndpointIn {
47
+ bus : self . bus ,
48
+ address : self . address | 0x80 ,
49
+ ep_type : ep_type,
50
+ max_packet_size,
51
+ interval : 1 ,
52
+ } ;
53
+
54
+ ( ep_out, ep_in)
55
+ }
56
+ }
57
+
58
+ pub trait Endpoint {
59
+ fn address ( & self ) -> u8 ;
60
+ fn ep_type ( & self ) -> EndpointType ;
61
+ fn max_packet_size ( & self ) -> u16 ;
62
+ fn interval ( & self ) -> u8 ;
63
+ }
64
+
65
+ pub struct EndpointOut < ' a , B : ' a + UsbBus > {
66
+ bus : & ' a B ,
67
+ address : u8 ,
68
+ ep_type : EndpointType ,
69
+ max_packet_size : u16 ,
70
+ interval : u8 ,
71
+ }
72
+
73
+ impl < ' a , B : UsbBus > EndpointOut < ' a , B > {
74
+ pub fn configure ( & self ) -> Result < ( ) > {
75
+ self . bus . configure_ep ( self . address , self . ep_type , self . max_packet_size )
76
+ }
77
+
78
+ pub fn read ( & self , data : & mut [ u8 ] ) -> Result < usize > {
79
+ self . bus . read ( self . address , data)
80
+ }
81
+
82
+ pub fn stall ( & self ) {
83
+ self . bus . stall ( self . address ) ;
84
+ }
85
+
86
+ pub fn unstall ( & self ) {
87
+ self . bus . unstall ( self . address ) ;
88
+ }
89
+ }
90
+
91
+ impl < ' a , B : UsbBus > Endpoint for EndpointOut < ' a , B > {
92
+ fn address ( & self ) -> u8 { self . address }
93
+ fn ep_type ( & self ) -> EndpointType { self . ep_type }
94
+ fn max_packet_size ( & self ) -> u16 { self . max_packet_size }
95
+ fn interval ( & self ) -> u8 { self . interval }
96
+ }
97
+
98
+ pub struct EndpointIn < ' a , B : ' a + UsbBus > {
99
+ bus : & ' a B ,
100
+ address : u8 ,
101
+ ep_type : EndpointType ,
102
+ max_packet_size : u16 ,
103
+ interval : u8 ,
104
+ }
105
+
106
+ impl < ' a , B : UsbBus > EndpointIn < ' a , B > {
107
+ pub fn configure ( & self ) -> Result < ( ) > {
108
+ self . bus . configure_ep ( self . address , self . ep_type , self . max_packet_size )
109
+ }
110
+
111
+ pub fn write ( & self , data : & [ u8 ] ) -> Result < usize > {
112
+ self . bus . write ( self . address , data)
113
+ }
114
+
115
+ pub fn stall ( & self ) {
116
+ self . bus . stall ( self . address ) ;
117
+ }
118
+
119
+ pub fn unstall ( & self ) {
120
+ self . bus . unstall ( self . address ) ;
121
+ }
122
+ }
123
+
124
+ impl < ' a , B : UsbBus > Endpoint for EndpointIn < ' a , B > {
125
+ fn address ( & self ) -> u8 { self . address }
126
+ fn ep_type ( & self ) -> EndpointType { self . ep_type }
127
+ fn max_packet_size ( & self ) -> u16 { self . max_packet_size }
128
+ fn interval ( & self ) -> u8 { self . interval }
129
+ }
130
+
131
+ #[ derive( Default ) ]
132
+ pub struct PollResult {
133
+ pub reset : bool ,
134
+ pub setup : bool ,
135
+ pub ep_in_complete : u16 ,
136
+ pub ep_out : u16 ,
137
+ }
0 commit comments