Skip to content

Commit 9cc9abe

Browse files
committed
usb-device-midi: Fix midi class driver descriptors.
Missing custom USB audio class standard descriptor extensions, as required by Windows usbaudio.sys (it seems). Also fixed the wTotalLength field which was incorrect for both the old and new versions of this code. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <[email protected]>
1 parent b876d14 commit 9cc9abe

File tree

1 file changed

+45
-20
lines changed
  • micropython/usb/usb-device-midi/usb/device

1 file changed

+45
-20
lines changed

micropython/usb/usb-device-midi/usb/device/midi.py

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@
1111
_INTERFACE_SUBCLASS_AUDIO_CONTROL = const(0x01)
1212
_INTERFACE_SUBCLASS_AUDIO_MIDISTREAMING = const(0x03)
1313

14+
# Audio subclass extends the standard endpoint descriptor
15+
# with two extra bytes
16+
_STD_DESC_AUDIO_ENDPOINT_LEN = const(9)
17+
_CLASS_DESC_ENDPOINT_LEN = const(5)
18+
19+
_STD_DESC_ENDPOINT_TYPE = const(0x5)
20+
1421
_JACK_TYPE_EMBEDDED = const(0x01)
1522
_JACK_TYPE_EXTERNAL = const(0x02)
1623

@@ -192,8 +199,15 @@ def desc_cfg(self, desc, itf_num, ep_num, strs):
192199
0x24, # bDescriptorType CS_INTERFACE
193200
0x01, # bDescriptorSubtype MS_HEADER
194201
0x0100, # BcdADC
195-
# wTotalLength: this descriptor, plus length of all Jack descriptors
196-
7 + 4 * (_JACK_IN_DESC_LEN + _JACK_OUT_DESC_LEN),
202+
# wTotalLength: of all class-specific descriptors
203+
7
204+
+ 2
205+
* (
206+
_JACK_IN_DESC_LEN
207+
+ _JACK_OUT_DESC_LEN
208+
+ _STD_DESC_AUDIO_ENDPOINT_LEN
209+
+ _CLASS_DESC_ENDPOINT_LEN
210+
),
197211
)
198212

199213
# The USB MIDI standard 1.0 allows modelling a baffling range of MIDI
@@ -222,26 +236,10 @@ def desc_cfg(self, desc, itf_num, ep_num, strs):
222236
self.ep_in = ep_num | _EP_IN_FLAG
223237

224238
# rx side, USB "in" endpoint and embedded MIDI IN Jacks
225-
desc.endpoint(self.ep_in, "bulk", 64, 0)
226-
desc.pack(
227-
"BBBBB",
228-
5, # bLength
229-
0x25, # bDescriptorType CS_ENDPOINT
230-
0x01, # bDescriptorSubtype MS_GENERAL
231-
1, # bNumEmbMIDIJack
232-
_EMB_OUT_JACK_ID,
233-
)
239+
_audio_endpoint(desc, self.ep_in, _EMB_OUT_JACK_ID)
234240

235241
# tx side, USB "out" endpoint and embedded MIDI OUT jacks
236-
desc.endpoint(self.ep_out, "bulk", 64, 0)
237-
desc.pack(
238-
"BBBBB",
239-
5, # bLength
240-
0x25, # bDescriptorType CS_ENDPOINT
241-
0x01, # bDescriptorSubtype MS_GENERAL
242-
1, # bNumEmbMIDIJack
243-
_EMB_IN_JACK_ID,
244-
)
242+
_audio_endpoint(desc, self.ep_out, _EMB_IN_JACK_ID)
245243

246244
def num_itfs(self):
247245
return 2
@@ -279,3 +277,30 @@ def _jack_out_desc(desc, bJackType, bJackID, bSourceId, bSourcePin):
279277
bSourcePin, # baSourcePin(1)
280278
0x00, # iJack, no string descriptor support yet
281279
)
280+
281+
282+
def _audio_endpoint(desc, bEndpointAddress, emb_jack_id):
283+
# Append a standard USB endpoint descriptor and the USB class endpoint descriptor
284+
# for this endpoint.
285+
#
286+
# Audio Class devices extend the standard endpoint descriptor with two extra bytes,
287+
# so we can't easily call desc.endpoint() for the first part.
288+
desc.pack(
289+
# Standard USB endpoint descriptor (plus audio tweaks)
290+
"<BBBBHBBB"
291+
# Class endpoint descriptor
292+
"BBBBB",
293+
_STD_DESC_AUDIO_ENDPOINT_LEN, # wLength
294+
_STD_DESC_ENDPOINT_TYPE, # bDescriptorType
295+
bEndpointAddress,
296+
2, # bmAttributes, bulk
297+
64, # wMaxPacketSize
298+
0, # bInterval
299+
0, # bRefresh (unused)
300+
0, # bSynchInterval (unused)
301+
_CLASS_DESC_ENDPOINT_LEN, # bLength
302+
0x25, # bDescriptorType CS_ENDPOINT
303+
0x01, # bDescriptorSubtype MS_GENERAL
304+
1, # bNumEmbMIDIJack
305+
emb_jack_id, # BaAssocJackID(1)
306+
)

0 commit comments

Comments
 (0)