Skip to content

Commit 51ccf8d

Browse files
committed
wip: revert usb_descriptor changes; use raw descriptors instead
1 parent 6cb751a commit 51ccf8d

10 files changed

Lines changed: 294 additions & 60 deletions

File tree

py/circuitpy_mpconfig.mk

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,9 +251,6 @@ CFLAGS += -DCIRCUITPY_REPL_BLE=$(CIRCUITPY_REPL_BLE)
251251
CIRCUITPY_REPL_UART ?= 0
252252
CFLAGS += -DCIRCUITPY_REPL_UART=$(CIRCUITPY_REPL_UART)
253253

254-
CIRCUITPY_REPL_USB ?= 1
255-
CFLAGS += -DCIRCUITPY_REPL_USB=$(CIRCUITPY_REPL_USB)
256-
257254
# Should busio.I2C() check for pullups?
258255
# Some boards in combination with certain peripherals may not want this.
259256
CIRCUITPY_REQUIRE_I2C_PULLUPS ?= 1

shared-module/storage/__init__.c

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,56 @@
4141
#include "supervisor/usb.h"
4242
#include "tusb.h"
4343

44+
static uint8_t[] storage_usb_msc_descriptor[] = {
45+
0x09, // 0 bLength
46+
0x04, // 1 bDescriptorType (Interface)
47+
0xFF, // 2 bInterfaceNumber [SET AT RUNTIME]
48+
0x00, // 3 bAlternateSetting
49+
0x02, // 4 bNumEndpoints 2
50+
0x08, // 5 bInterfaceClass: MSC
51+
0x06, // 6 bInterfaceSubClass: TRANSPARENT
52+
0x50, // 7 bInterfaceProtocol: BULK
53+
0x00, // 8 iInterface (String Index) [SET AT RUNTIME]
54+
55+
0x07, // 9 bLength
56+
0x05, // 10 bDescriptorType (Endpoint)
57+
0xFF, // 11 bEndpointAddress (IN/D2H) [SET AT RUNTIME: 0x8 | number]
58+
0x02, // 12 bmAttributes (Bulk)
59+
0x40, 0x00, // 13,14 wMaxPacketSize 64
60+
0x00, // 15 bInterval 0 (unit depends on device speed)
61+
62+
0x07, // 16 bLength
63+
0x05, // 17 bDescriptorType (Endpoint)
64+
0xFF, // 18 bEndpointAddress (OUT/H2D) [SET AT RUNTIME]
65+
0x02, // 19 bmAttributes (Bulk)
66+
0x40, 0x00, // 20 wMaxPacketSize 64
67+
0x00, // 21 bInterval 0 (unit depends on device speed)
68+
};
69+
70+
// Indices into usb_msc_descriptor for values that must be set at runtime.
71+
72+
#define MSC_INTERFACE_NUMBER_INDEX 2
73+
#define MSC_INTERFACE_STRING_INDEX 8
74+
#define MSC_IN_ENDPOINT_INDEX 11
75+
#define MSC_OUT_ENDPOINT_INDEX 118
76+
4477
// Is the MSC device enabled?
45-
static bool usb_storage_enabled;
78+
bool storage_usb_enabled;
79+
80+
size_t storage_usb_desc_length(void) {
81+
return sizeof(usb_msc_descriptor);
82+
}
83+
84+
size_t storage_usb_add_desc(uint8_t *desc_buf, uint8_t interface_number, uint8_t in_endpoint_address,
85+
uint8_t out_endpoint_address, uint8_t interface_string_index) {
86+
memcpy(descriptor_buf, storage_usb_msc_descriptor, sizeof(storage_usb_msc_descriptor));
87+
desc_buf[MSC_INTERFACE_NUMBER_INDEX] = interface_number;
88+
desc_buf[MSC_INTERFACE_STRING_INDEX] = interface_string_index;
89+
desc_buf[MSC_IN_ENDPOINT_INDEX] = in_endpoint_address;
90+
desc_buf[MSC_OUT_ENDPOINT_INDEX] = 0x80 | out_endpoint_address;
91+
return sizeof(usb_msc_descriptor);
92+
}
93+
4694

4795
STATIC mp_obj_t mp_vfs_proxy_call(mp_vfs_mount_t *vfs, qstr meth_name, size_t n_args, const mp_obj_t *args) {
4896
if (vfs == MP_VFS_NONE) {
@@ -62,7 +110,7 @@ STATIC mp_obj_t mp_vfs_proxy_call(mp_vfs_mount_t *vfs, qstr meth_name, size_t n_
62110
}
63111

64112
void storage_init(void) {
65-
usb_storage_enabled = true;
113+
storage_usb_enabled = true;
66114
}
67115

68116
void common_hal_storage_mount(mp_obj_t vfs_obj, const char *mount_path, bool readonly) {
@@ -180,6 +228,6 @@ bool common_hal_storage_configure_usb(bool enabled) {
180228
if (tud_connected()) {
181229
return false;
182230
}
183-
usb_storage_enabled = enabled;
231+
storage_usb_enabled = enabled;
184232
return true;
185233
}

shared-module/storage/__init__.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@
2727
#ifndef SHARED_MODULE_STORAGE___INIT___H
2828
#define SHARED_MODULE_STORAGE___INIT___H
2929

30+
extern bool storage_usb_enabled;
31+
3032
void storage_init(void);
33+
size_t storage_usb_desc_length(void);
34+
size_t storage_usb_add_desc(uint8_t *desc_buf, uint8_t interface_number,
35+
uint8_t in_endpoint_address, uint8_t out_endpoint_address,
36+
uint8_t interface_string_index);
3137

3238
#endif // SHARED_MODULE_STORAGE___INIT___H

shared-module/usb_cdc/__init__.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@
3838
#error CFG_TUD_CDC must be exactly 2
3939
#endif
4040

41-
static bool usb_cdc_repl_enabled;
42-
static bool usb_cdc_data_enabled;
41+
bool usb_cdc_repl_enabled;
42+
bool usb_cdc_data_enabled;
4343

4444
static usb_cdc_serial_obj_t usb_cdc_repl_obj = {
4545
.base.type = &usb_cdc_serial_type,

shared-module/usb_cdc/__init__.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929

3030
#include "py/objtuple.h"
3131

32+
extern bool usb_cdc_repl_enabled;
33+
extern bool usb_cdc_data_enabled;
34+
3235
void usb_cdc_init(void);
3336

3437
#endif /* SHARED_MODULE_USB_CDC___INIT___H */

shared-module/usb_midi/__init__.c

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,113 @@
3838

3939
supervisor_allocation *usb_midi_allocation;
4040

41+
static uint8_t[] usb_midi_descriptor[] = {
42+
0x09, // 0 bLength
43+
0x04, // 1 bDescriptorType (Interface)
44+
0xFF, // 2 bInterfaceNumber [SET AT RUNTIME]
45+
0x00, // 3 bAlternateSetting
46+
0x00, // 4 bNumEndpoints 0
47+
0x01, // 5 bInterfaceClass (Audio)
48+
0x01, // 6 bInterfaceSubClass (Audio Control)
49+
0x00, // 7 bInterfaceProtocol
50+
0x00, // 8 iInterface (String Index) [SET AT RUNTIME]
51+
52+
0x09, // 9 bLength
53+
0x24, // 10 bDescriptorType (See Next Line)
54+
0x01, // 11 bDescriptorSubtype (CS_INTERFACE -> HEADER)
55+
0x00, 0x01, // 12,13 bcdADC 1.00
56+
0x09, 0x00, // 14,15 wTotalLength 9
57+
0x01, // 16 binCollection 0x01
58+
0xFF, // 17 baInterfaceNr [SET AT RUNTIME: one-element list: same as 20]
59+
60+
0x09, // 18 bLength
61+
0x04, // 19 bDescriptorType (Interface)
62+
0xFF, // 20 bInterfaceNumber [SET AT RUNTIME]
63+
0x00, // 21 bAlternateSetting
64+
0x02, // 22 bNumEndpoints 2
65+
0x01, // 23 bInterfaceClass (Audio)
66+
0x03, // 24 bInterfaceSubClass (MIDI Streaming)
67+
0x00, // 25 bInterfaceProtocol
68+
0x0A, // 26 iInterface (String Index) [SET AT RUNTIME]
69+
70+
0x07, // 27 bLength
71+
0x24, // 28 bDescriptorType (See Next Line)
72+
0x01, 0x00, 0x01, 0x25, 0x00, // 29,30,31,32,33
73+
0x06, // 34 bLength
74+
0x24, // 35 bDescriptorType (See Next Line)
75+
0x02, 0x01, 0x01, 0x08, // 36,37,38,39
76+
0x06, // 40 bLength
77+
0x24, // 41 bDescriptorType (See Next Line)
78+
0x02, 0x02, 0x02, 0x00, // 42,43,44,45
79+
0x09, // 46 bLength
80+
0x24, // 47 bDescriptorType (See Next Line)
81+
0x03, 0x01, 0x03, 0x01, 0x02, 0x01, 0x09, // 48,49,50,51,52,53,54
82+
0x09, // 56 bLength
83+
0x24, // 57 bDescriptorType (See Next Line)
84+
0x03, 0x02, 0x04, 0x01, 0x01, 0x01, 0x00, // 58,59,60,61,62,63,64
85+
0x07, // 65 bLength
86+
0x05, // 66 bDescriptorType (See Next Line)
87+
0xFF, // 67 bEndpointAddress (OUT/H2D) [SET AT RUNTIME]
88+
0x02, // 68 bmAttributes (Bulk)
89+
0x40, 0x00, // 69,70 wMaxPacketSize 64
90+
0x00, // 71 bInterval 0 (unit depends on device speed)
91+
92+
0x05, // 72 bLength
93+
0x25, // 73 bDescriptorType (See Next Line)
94+
0x01, 0x01, 0x01, // 74,75,76
95+
0x07, // 77 bLength
96+
0x05, // 78 bDescriptorType (See Next Line)
97+
0xFF, // 79 bEndpointAddress (IN/D2H) [SET AT RUNTIME: 0x8 | number]
98+
0x02, // 80 bmAttributes (Bulk)
99+
0x40, 0x00, // 81,82 wMaxPacketSize 64
100+
0x00, // 83 bInterval 0 (unit depends on device speed)
101+
102+
0x05, // 84 bLength
103+
0x25, // 85 bDescriptorType (See Next Line)
104+
0x01, 0x01, 0x03, // 86,87,88
105+
};
106+
41107
// Is the USB MIDI device enabled?
42-
static bool usb_midi_enabled;
108+
bool usb_midi_enabled;
109+
110+
// Indices into usb_midi_descriptor for values that must be set at runtime.
111+
112+
#define MIDI_AUDIO_CONTROL_INTERFACE_NUMBER_INDEX 2
113+
#define MIDI_AUDIO_CONTROL_INTERFACE_STRING_INDEX 8
114+
115+
// These two get the same value.
116+
#define MIDI_MIDI_STREAMING_INTERFACE_NUMBER_INDEX 20
117+
#define MIDI_MIDI_STREAMING_INTERFACE_NUMBER_XREF_INDEX 17
118+
119+
#define MIDI_MIDI_STREAMING_INTERFACE_STRING_INDEX 26
120+
121+
#define MIDI_MIDI_STREAMING_OUT_ENDPOINT_INDEX 67
122+
#define MIDI_MIDI_STREAMING_IN_ENDPOINT_INDEX 79
123+
124+
size_t usb_midi_desc_length(void) {
125+
return sizeof(usb_midi_descriptor);
126+
}
127+
128+
size_t usb_midi_add_desc(uint8_t *desc_buf,
129+
uint8_t audio_control_interface_number,
130+
uint8_t midi_streaming_interface_number,
131+
uint8_t midi_streaming_in_endpoint_address,
132+
uint8_t midi_streaming_out_endpoint_address,
133+
uint8_t audio_control_interface_string,
134+
uint8_t midi_streaming_interface_string) {
135+
memcpy(descriptor_buf, usb_midi_descriptor, sizeof(usb_midi_descriptor));
136+
desc_buf[MIDI_AUDIO_CONTROL_INTERFACE_NUMBER_INDEX] = audio_control_interface_number;
137+
desc_buf[MIDI_AUDIO_CONTROL_INTERFACE_STRING_INDEX] = audio_control_interface_string;
138+
139+
desc_buf[MIDI_MIDI_STREAMING_INTERFACE_NUMBER_INDEX] = midi_streaming_interface_number;
140+
desc_buf[MIDI_MIDI_STREAMING_INTERFACE_NUMBER_XREF_INDEX] = midi_streaming_interface_number;
141+
desc_buf[MIDI_MIDI_STREAMING_INTERFACE_STRING_INDEX] = midi_streaming_interface_string;
142+
143+
desc_buf[MSC_IN_ENDPOINT_INDEX] = midi_streaming_in_endpoint_address;
144+
desc_buf[MSC_OUT_ENDPOINT_INDEX] = 0x80 | midi_streaming_out_endpoint_address;
145+
return sizeof(usb_midi_descriptor);
146+
}
147+
43148

44149
void usb_midi_init(void) {
45150
usb_midi_enabled = true;

shared-module/usb_midi/__init__.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,18 @@
2727
#ifndef SHARED_MODULE_USB_MIDI___INIT___H
2828
#define SHARED_MODULE_USB_MIDI___INIT___H
2929

30+
extern bool usb_midi_enabled;
31+
3032
void usb_midi_init(void);
3133
void usb_midi_usb_init(void);
34+
size_t usb_midi_desc_length(void);
35+
size_t usb_midi_add_desc(uint8_t *desc_buf,
36+
uint8_t audio_control_interface_number,
37+
uint8_t midi_streaming_interface_number,
38+
uint8_t midi_streaming_in_endpoint_address,
39+
uint8_t midi_streaming_out_endpoint_address,
40+
uint8_t audio_control_interface_string,
41+
uint8_t midi_streaming_interface_string);
42+
3243

3344
#endif /* SHARED_MODULE_USB_MIDI___INIT___H */

supervisor/shared/usb/usb_desc.c

Lines changed: 113 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,29 @@
2525
*/
2626

2727
#include "lib/tinyusb/src/tusb.h"
28+
29+
#if CIRCUITPY_USB_CDC
30+
#include "shared-module/storage/__init__.h"
31+
#endif
32+
33+
#if CIRCUITPY_USB_HID
34+
#include "shared-module/usb_hid/__init__.h"
35+
#endif
36+
37+
#if CIRCUITPY_USB_MIDI
38+
#include "shared-module/usb_midi/__init__.h"
39+
#endif
40+
41+
#if CIRCUITPY_USB_MSC
42+
#include "shared-module/storage/__init__.h"
43+
#endif
44+
2845
#include "shared-module/usb_hid/Device.h"
2946

3047
#include "genhdr/autogen_usb_descriptor.h"
3148

49+
static uint8_t *config_desc;
50+
3251
// Invoked when received GET DEVICE DESCRIPTOR
3352
// Application return pointer to descriptor
3453
uint8_t const *tud_descriptor_device_cb(void) {
@@ -40,7 +59,100 @@ uint8_t const *tud_descriptor_device_cb(void) {
4059
// Descriptor contents must exist long enough for transfer to complete
4160
uint8_t const *tud_descriptor_configuration_cb(uint8_t index) {
4261
(void)index; // for multiple configurations
43-
return usb_desc_cfg;
62+
63+
size_t total_descriptor_length = 0;
64+
65+
// CDC should be first, for compatibility with Adafruit Windows 7 drivers.
66+
// In the past, the order has been CDC, MSC, MIDI, HID, so preserve
67+
// that order.
68+
#if CIRCUITPY_USB_CDC
69+
if (usb_cdc_repl_enabled) {
70+
total_descriptor_length += usb_cdc_desc_length();
71+
}
72+
if (usb_cdc_data_enabled) {
73+
total_descriptor_length += usb_cdc_desc_length();
74+
}
75+
#endif
76+
77+
#if CIRCUITPY_USB_MSC
78+
if (storage_usb_enabled) {
79+
total_descriptor_length += storage_usb_desc_length();
80+
}
81+
#endif
82+
83+
#if CIRCUITPY_USB_MIDI
84+
if (usb_midi_enabled) {
85+
total_descriptor_length += usb_midi_desc_length();
86+
}
87+
#endif
88+
89+
#if CIRCUITPY_USB_HID
90+
if (usb_hid_enabled) {
91+
total_descriptor_length += usb_hid_desc_length();
92+
}
93+
#endif
94+
95+
// Now we now how big the configuration descriptor will be.
96+
config_desc = m_malloc(total_descriptor_length, false);
97+
98+
// Number interfaces and endpoints.
99+
// Endpoint 0 is already used for USB control
100+
uint8_t current_interface = 0;
101+
uint8_t current_endpoint = 1;
102+
uint16_t current_interface_string = 1;
103+
104+
uint8_t *desc_buf_remaining = config_desc;
105+
106+
#if CIRCUITPY_USB_CDC
107+
if (usb_cdc_repl_enabled) {
108+
// Concatenate and fix up the CDC REPL descriptor.
109+
}
110+
if (usb_cdc_data_enabled) {
111+
// Concatenate and fix up the CDC data descriptor.
112+
}
113+
#endif
114+
115+
#if CIRCUITPY_USB_MSC
116+
if (storage_usb_enabled) {
117+
// Concatenate and fix up the MSC descriptor.
118+
desc_buf_remaining += storage_usb_add_desc(
119+
desc_buf_remaining, current_interface,
120+
current_endpoint, // in
121+
current_endpoint, // out
122+
current_interface_string_index);
123+
current_interface++;
124+
current_endpoint++;
125+
current_interface_string++;
126+
}
127+
#endif
128+
129+
#if CIRCUITPY_USB_MIDI
130+
if (usb_midi_enabled) {
131+
// Concatenate and fix up the MIDI descriptor.
132+
desc_buf_remaining += usb_midi_add_desc(
133+
desc_buf_remaining,
134+
current_interface, // audio control
135+
current_interface + 1, // MIDI streaming
136+
current_endpoint, // in
137+
current_endpoint, // out
138+
current_interface_string, // audio control
139+
current_interface_string + 1 // MIDI streaming
140+
);
141+
current_interface += 2;
142+
current_endpoint++;
143+
current_interface_string += 2;
144+
145+
}
146+
#endif
147+
148+
#if CIRCUITPY_USB_HID
149+
if (usb_hid_enabled) {
150+
// Concatenate and fix up the HID descriptor (not the report descriptors).
151+
}
152+
#endif
153+
154+
155+
return config_desc;
44156
}
45157

46158
#if CIRCUITPY_USB_HID

0 commit comments

Comments
 (0)