Skip to content

Commit 7c20bfb

Browse files
committed
refactor(usb): dynamic endpoint descriptor generation
Replace static endpoint variables with EndpointIN and EndpointOUT functions. Allows flexible endpoint remapping across USB configs.
1 parent 4204f3d commit 7c20bfb

7 files changed

Lines changed: 83 additions & 114 deletions

File tree

builder/sizes_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func TestBinarySize(t *testing.T) {
4444
// microcontrollers
4545
{"hifive1b", "examples/echo", 3680, 280, 0, 2252},
4646
{"microbit", "examples/serial", 2694, 342, 8, 2248},
47-
{"wioterminal", "examples/pininterrupt", 7074, 1510, 120, 7248},
47+
{"wioterminal", "examples/pininterrupt", 3541, 799, 88, 7008},
4848

4949
// TODO: also check wasm. Right now this is difficult, because
5050
// wasm binaries are run through wasm-opt and therefore the

src/machine/usb/descriptor/cdc.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ var InterfaceCDCData = InterfaceType{
150150
data: interfaceCDCData[:],
151151
}
152152

153+
// EP1 IN : CDC Call Management
154+
// EP2 OUT: CDC OUT
155+
// EP2 IN : CDC IN
153156
var CDC = Descriptor{
154157
Device: DeviceCDC.Bytes(),
155158
Configuration: Append([][]byte{
@@ -160,9 +163,9 @@ var CDC = Descriptor{
160163
ClassSpecificCDCCallManagement.Bytes(),
161164
ClassSpecificCDCACM.Bytes(),
162165
ClassSpecificCDCUnion.Bytes(),
163-
EndpointEP1IN.Bytes(),
166+
EndpointIN(EndpointEP1, TransferTypeInterrupt, 0x10, 0x10).Bytes(),
164167
InterfaceCDCData.Bytes(),
165-
EndpointEP2OUT.Bytes(),
166-
EndpointEP3IN.Bytes(),
168+
EndpointOUT(EndpointEP2, TransferTypeBulk, 0x40, 0x00).Bytes(),
169+
EndpointIN(EndpointEP3, TransferTypeBulk, 0x40, 0x00).Bytes(),
167170
}),
168171
}

src/machine/usb/descriptor/endpoint.go

Lines changed: 34 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -15,104 +15,44 @@ const (
1515
TransferTypeInterrupt
1616
)
1717

18-
var endpointEP1IN = [endpointTypeLen]byte{
19-
endpointTypeLen,
20-
TypeEndpoint,
21-
0x81, // EndpointAddress
22-
0x03, // Attributes
23-
0x10, // MaxPacketSizeL
24-
0x00, // MaxPacketSizeH
25-
0x10, // Interval
26-
}
27-
28-
var EndpointEP1IN = EndpointType{
29-
data: endpointEP1IN[:],
30-
}
31-
32-
var endpointEP2OUT = [endpointTypeLen]byte{
33-
endpointTypeLen,
34-
TypeEndpoint,
35-
0x02, // EndpointAddress
36-
0x02, // Attributes
37-
0x40, // MaxPacketSizeL
38-
0x00, // MaxPacketSizeH
39-
0x00, // Interval
40-
}
41-
42-
var EndpointEP2OUT = EndpointType{
43-
data: endpointEP2OUT[:],
44-
}
18+
type EndpointNumber uint8
4519

46-
var endpointEP3IN = [endpointTypeLen]byte{
47-
endpointTypeLen,
48-
TypeEndpoint,
49-
0x83, // EndpointAddress
50-
0x02, // Attributes
51-
0x40, // MaxPacketSizeL
52-
0x00, // MaxPacketSizeH
53-
0x00, // Interval
54-
}
55-
56-
var EndpointEP3IN = EndpointType{
57-
data: endpointEP3IN[:],
58-
}
59-
60-
var endpointEP4IN = [endpointTypeLen]byte{
61-
endpointTypeLen,
62-
TypeEndpoint,
63-
0x84, // EndpointAddress
64-
0x03, // Attributes
65-
0x40, // MaxPacketSizeL
66-
0x00, // MaxPacketSizeH
67-
0x01, // Interval
68-
}
69-
70-
var EndpointEP4IN = EndpointType{
71-
data: endpointEP4IN[:],
72-
}
73-
74-
var endpointEP5OUT = [endpointTypeLen]byte{
75-
endpointTypeLen,
76-
TypeEndpoint,
77-
0x05, // EndpointAddress
78-
0x03, // Attributes
79-
0x40, // MaxPacketSizeL
80-
0x00, // MaxPacketSizeH
81-
0x01, // Interval
82-
}
83-
84-
var EndpointEP5OUT = EndpointType{
85-
data: endpointEP5OUT[:],
86-
}
87-
88-
// Mass Storage Class bulk in endpoint
89-
var endpointMSCIN = [endpointTypeLen]byte{
90-
endpointTypeLen,
91-
TypeEndpoint,
92-
0x86, // EndpointAddress
93-
TransferTypeBulk, // Attributes
94-
0x40, // MaxPacketSizeL (64 bytes)
95-
0x00, // MaxPacketSizeH
96-
0x00, // Interval
97-
}
20+
const (
21+
EndpointEP1 EndpointNumber = iota
22+
EndpointEP2
23+
EndpointEP3
24+
EndpointEP4
25+
)
9826

99-
var EndpointMSCIN = EndpointType{
100-
data: endpointMSCIN[:],
101-
}
27+
const (
28+
maxEndpoints = 4
29+
)
10230

103-
// Mass Storage Class bulk out endpoint
104-
var endpointMSCOUT = [endpointTypeLen]byte{
105-
endpointTypeLen,
106-
TypeEndpoint,
107-
0x07, // EndpointAddress
108-
TransferTypeBulk, // Attributes
109-
0x40, // MaxPacketSizeL (64 bytes)
110-
0x00, // MaxPacketSizeH
111-
0x00, // Interval
112-
}
31+
var (
32+
endpointEPIn = [maxEndpoints][endpointTypeLen]byte{}
33+
endpointEPOut = [maxEndpoints][endpointTypeLen]byte{}
34+
)
11335

114-
var EndpointMSCOUT = EndpointType{
115-
data: endpointMSCOUT[:],
36+
func EndpointIN(ep EndpointNumber, transferType uint8, maxPacketSize uint16, interval uint8) EndpointType {
37+
e := EndpointType{data: endpointEPIn[ep][:]}
38+
e.Length(endpointTypeLen)
39+
e.Type(TypeEndpoint)
40+
e.EndpointAddress(uint8(ep+1) | 0x80) // EndpointNumber is 0-based, addresses are 1-based
41+
e.Attributes(transferType)
42+
e.MaxPacketSize(maxPacketSize)
43+
e.Interval(interval)
44+
return e
45+
}
46+
47+
func EndpointOUT(ep EndpointNumber, transferType uint8, maxPacketSize uint16, interval uint8) EndpointType {
48+
e := EndpointType{data: endpointEPOut[ep][:]}
49+
e.Length(endpointTypeLen)
50+
e.Type(TypeEndpoint)
51+
e.EndpointAddress(uint8(ep + 1)) // EndpointNumber is 0-based, addresses are 1-based
52+
e.Attributes(transferType)
53+
e.MaxPacketSize(maxPacketSize)
54+
e.Interval(interval)
55+
return e
11656
}
11757

11858
const (

src/machine/usb/descriptor/hid.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ var ClassHID = ClassHIDType{
111111
data: classHID[:],
112112
}
113113

114+
// EP1 IN : CDC Call Management
115+
// EP1 OUT: HID OUT
116+
// EP2 IN : HID IN
117+
// EP2 OUT: CDC OUT
118+
// EP3 IN : CDC IN
114119
var CDCHID = Descriptor{
115120
Device: DeviceCDC.Bytes(),
116121
Configuration: Append([][]byte{
@@ -121,14 +126,14 @@ var CDCHID = Descriptor{
121126
ClassSpecificCDCACM.Bytes(),
122127
ClassSpecificCDCUnion.Bytes(),
123128
ClassSpecificCDCCallManagement.Bytes(),
124-
EndpointEP1IN.Bytes(),
129+
EndpointIN(EndpointEP1, TransferTypeInterrupt, 0x10, 0x10).Bytes(),
125130
InterfaceCDCData.Bytes(),
126-
EndpointEP2OUT.Bytes(),
127-
EndpointEP3IN.Bytes(),
131+
EndpointOUT(EndpointEP2, TransferTypeBulk, 0x40, 0x00).Bytes(),
132+
EndpointIN(EndpointEP3, TransferTypeBulk, 0x40, 0x00).Bytes(),
128133
InterfaceHID.Bytes(),
129134
ClassHID.Bytes(),
130-
EndpointEP4IN.Bytes(),
131-
EndpointEP5OUT.Bytes(),
135+
EndpointIN(EndpointEP2, TransferTypeInterrupt, 0x40, 0x01).Bytes(),
136+
EndpointOUT(EndpointEP1, TransferTypeInterrupt, 0x40, 0x01).Bytes(),
132137
}),
133138
HID: map[uint16][]byte{
134139
2: Append([][]byte{ // Update ClassLength in classHID whenever the array length is modified!

src/machine/usb/descriptor/joystick.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,11 @@ var JoystickDefaultHIDReport = Append([][]byte{
121121
// CDCJoystick requires that you append the JoystickDescriptor
122122
// to the Configuration before using. This is in order to support
123123
// custom configurations.
124+
// EP1 IN : CDC Call Management
125+
// EP1 OUT: HID OUT
126+
// EP2 IN : HID IN
127+
// EP2 OUT: CDC OUT
128+
// EP2 IN : CDC IN
124129
var CDCJoystick = Descriptor{
125130
Device: DeviceJoystick.Bytes(),
126131
Configuration: Append([][]byte{
@@ -131,14 +136,14 @@ var CDCJoystick = Descriptor{
131136
ClassSpecificCDCACM.Bytes(),
132137
ClassSpecificCDCUnion.Bytes(),
133138
ClassSpecificCDCCallManagement.Bytes(),
134-
EndpointEP1IN.Bytes(),
139+
EndpointIN(EndpointEP1, TransferTypeInterrupt, 0x10, 0x10).Bytes(),
135140
InterfaceCDCData.Bytes(),
136-
EndpointEP2OUT.Bytes(),
137-
EndpointEP3IN.Bytes(),
141+
EndpointOUT(EndpointEP2, TransferTypeBulk, 0x40, 0x00).Bytes(),
142+
EndpointIN(EndpointEP3, TransferTypeBulk, 0x40, 0x00).Bytes(),
138143
InterfaceHIDJoystick.Bytes(),
139144
ClassHIDJoystick.Bytes(),
140-
EndpointEP4IN.Bytes(),
141-
EndpointEP5OUT.Bytes(),
145+
EndpointIN(EndpointEP2, TransferTypeInterrupt, 0x40, 0x01).Bytes(),
146+
EndpointOUT(EndpointEP1, TransferTypeInterrupt, 0x40, 0x01).Bytes(),
142147
}),
143148
HID: map[uint16][]byte{},
144149
}

src/machine/usb/descriptor/midi.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,11 @@ var ConfigurationCDCMIDI = ConfigurationType{
218218
data: configurationCDCMIDI[:],
219219
}
220220

221+
// EP1 IN : CDC Call Management
222+
// EP2 OUT: CDC OUT
223+
// EP3 IN : CDC IN
224+
// EP6 IN : MIDI IN (custom endpoint descriptor)
225+
// EP7 OUT: MIDI OUT (custom endpoint descriptor)
221226
var CDCMIDI = Descriptor{
222227
Device: DeviceCDC.Bytes(),
223228
Configuration: Append([][]byte{
@@ -228,10 +233,10 @@ var CDCMIDI = Descriptor{
228233
ClassSpecificCDCACM.Bytes(),
229234
ClassSpecificCDCUnion.Bytes(),
230235
ClassSpecificCDCCallManagement.Bytes(),
231-
EndpointEP1IN.Bytes(),
236+
EndpointIN(EndpointEP1, TransferTypeInterrupt, 0x10, 0x10).Bytes(),
232237
InterfaceCDCData.Bytes(),
233-
EndpointEP2OUT.Bytes(),
234-
EndpointEP3IN.Bytes(),
238+
EndpointOUT(EndpointEP2, TransferTypeBulk, 0x40, 0x00).Bytes(),
239+
EndpointIN(EndpointEP3, TransferTypeBulk, 0x40, 0x00).Bytes(),
235240
InterfaceAssociationMIDI.Bytes(),
236241
InterfaceAudio.Bytes(),
237242
ClassSpecificAudioInterface.Bytes(),

src/machine/usb/descriptor/msc.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,18 @@ var ConfigurationMSC = ConfigurationType{
5252
data: configurationMSC[:],
5353
}
5454

55+
var (
56+
EndpointMSCIN = EndpointIN(EndpointEP2, TransferTypeBulk, 0x40, 0x00)
57+
EndpointMSCOUT = EndpointOUT(EndpointEP3, TransferTypeBulk, 0x40, 0x00)
58+
)
59+
5560
// Mass Storage Class
61+
// EP1 IN : CDC Call Management
62+
// EP1 OUT: x
63+
// EP2 IN : MSC IN
64+
// EP2 OUT: CDC OUT
65+
// EP3 IN : CDC IN
66+
// EP3 OUT: MSC OUT
5667
var MSC = Descriptor{
5768
Device: DeviceCDC.Bytes(),
5869
Configuration: Append([][]byte{
@@ -63,10 +74,10 @@ var MSC = Descriptor{
6374
ClassSpecificCDCACM.Bytes(),
6475
ClassSpecificCDCUnion.Bytes(),
6576
ClassSpecificCDCCallManagement.Bytes(),
66-
EndpointEP1IN.Bytes(),
77+
EndpointIN(EndpointEP1, TransferTypeInterrupt, 0x10, 0x10).Bytes(),
6778
InterfaceCDCData.Bytes(),
68-
EndpointEP2OUT.Bytes(),
69-
EndpointEP3IN.Bytes(),
79+
EndpointOUT(EndpointEP2, TransferTypeBulk, 0x40, 0x00).Bytes(),
80+
EndpointIN(EndpointEP3, TransferTypeBulk, 0x40, 0x00).Bytes(),
7081
InterfaceAssociationMSC.Bytes(),
7182
InterfaceMSC.Bytes(),
7283
EndpointMSCIN.Bytes(),

0 commit comments

Comments
 (0)