MSC, CDC, HID keyboard definitely working · csamuelson/circuitpython@abfb020 · GitHub
Skip to content

Commit abfb020

Browse files
committed
MSC, CDC, HID keyboard definitely working
1 parent f06d545 commit abfb020

8 files changed

Lines changed: 69 additions & 30 deletions

File tree

main.c

Lines changed: 0 additions & 6 deletions

shared-module/usb_cdc/__init__.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,9 @@ bool common_hal_usb_cdc_configure_usb(bool repl_enabled, bool data_enabled) {
224224
return false;
225225
}
226226

227+
// Right now these objects contain no heap objects, but if that changes,
228+
// they will need to be protected against gc.
229+
227230
usb_cdc_repl_is_enabled = repl_enabled;
228231
usb_cdc_set_repl(repl_enabled ? MP_OBJ_FROM_PTR(&usb_cdc_repl_obj) : mp_const_none);
229232

shared-module/usb_hid/Device.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ static const uint8_t keyboard_report_descriptor[] = {
7171
};
7272

7373
const usb_hid_device_obj_t usb_hid_device_keyboard_obj = {
74+
.base = {
75+
.type = &usb_hid_device_type,
76+
},
7477
.report_descriptor = keyboard_report_descriptor,
7578
.report_descriptor_length = sizeof(keyboard_report_descriptor),
7679
.usage_page = 0x01,
@@ -119,6 +122,9 @@ static const uint8_t mouse_report_descriptor[] = {
119122
};
120123

121124
const usb_hid_device_obj_t usb_hid_device_mouse_obj = {
125+
.base = {
126+
.type = &usb_hid_device_type,
127+
},
122128
.report_descriptor = mouse_report_descriptor,
123129
.report_descriptor_length = sizeof(mouse_report_descriptor),
124130
.usage_page = 0x01,
@@ -145,6 +151,9 @@ static const uint8_t consumer_control_report_descriptor[] = {
145151
};
146152

147153
const usb_hid_device_obj_t usb_hid_device_consumer_control_obj = {
154+
.base = {
155+
.type = &usb_hid_device_type,
156+
},
148157
.report_descriptor = consumer_control_report_descriptor,
149158
.report_descriptor_length = sizeof(consumer_control_report_descriptor),
150159
.usage_page = 0x0C,

shared-module/usb_hid/__init__.c

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ static supervisor_allocation *hid_report_descriptor_allocation;
8383
static usb_hid_device_obj_t hid_devices[MAX_HID_DEVICES];
8484
static mp_int_t hid_devices_num;
8585

86+
// This tuple is store in usb_hid.devices.
87+
static mp_obj_tuple_t *hid_devices_tuple;
88+
8689
static mp_obj_tuple_t default_hid_devices_tuple = {
8790
.base = {
8891
.type = &mp_type_tuple,
@@ -132,6 +135,19 @@ size_t usb_hid_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interfac
132135
return sizeof(usb_hid_descriptor_template);
133136
}
134137

138+
// Make up a fresh tuple containing the device objects saved in the static
139+
// devices table. Save the tuple in usb_hid.devices.
140+
static void usb_hid_set_devices_from_hid_devices(void) {
141+
mp_obj_t tuple_items[hid_devices_num];
142+
for (mp_int_t i = 0; i < hid_devices_num; i++) {
143+
tuple_items[i] = &hid_devices[i];
144+
}
145+
146+
// Remember tuple for gc purposes.
147+
hid_devices_tuple = mp_obj_new_tuple(hid_devices_num, tuple_items);
148+
usb_hid_set_devices(hid_devices_tuple);
149+
}
150+
135151
bool common_hal_usb_hid_configure_usb(const mp_obj_t devices) {
136152
// We can't change the devices once we're connected.
137153
if (tud_connected()) {
@@ -151,20 +167,16 @@ bool common_hal_usb_hid_configure_usb(const mp_obj_t devices) {
151167
memcpy(&hid_devices[i], device, sizeof(usb_hid_device_obj_t));
152168
}
153169

170+
usb_hid_set_devices_from_hid_devices();
171+
154172
return true;
155173
}
156174

175+
// Called when HID devices are ready to be used, when code.py or the REPL starts running.
157176
void usb_hid_setup_devices(void) {
158-
// Make up a fresh tuple containing the device objects are saved in the static
159-
// devices table. Save the tuple in usb_hid.devices.
177+
usb_hid_set_devices_from_hid_devices();
160178

161-
mp_obj_t tuple_items[hid_devices_num];
162-
for (mp_int_t i = 0; i < hid_devices_num; i++) {
163-
tuple_items[i] = &hid_devices[i];
164-
}
165-
usb_hid_set_devices(mp_obj_new_tuple(hid_devices_num, tuple_items));
166-
167-
// Create report buffers on the heap.
179+
// Create report buffers on the heap.
168180
for (mp_int_t i = 0; i < hid_devices_num; i++) {
169181
usb_hid_device_create_report_buffers(&hid_devices[i]);
170182
}
@@ -174,10 +186,7 @@ void usb_hid_setup_devices(void) {
174186
size_t usb_hid_report_descriptor_length(void) {
175187
size_t total_hid_report_descriptor_length = 0;
176188
for (mp_int_t i = 0; i < hid_devices_num; i++) {
177-
// hid_devices has already been validated to contain only usb_hid_device_obj_t objects.
178-
usb_hid_device_obj_t *device =
179-
MP_OBJ_TO_PTR(mp_obj_subscr(hid_devices, MP_OBJ_NEW_SMALL_INT(i), MP_OBJ_SENTINEL));
180-
total_hid_report_descriptor_length += device->report_descriptor_length;
189+
total_hid_report_descriptor_length += hid_devices[i].report_descriptor_length;
181190
}
182191

183192
// Don't need space for a report id if there's only one device.
@@ -205,9 +214,15 @@ void usb_hid_build_report_descriptor(uint8_t* report_descriptor_space, size_t re
205214
// Copy the whole descriptor and fill in the report id.
206215
memcpy(report_descriptor_start, device->report_descriptor, device->report_descriptor_length);
207216
report_descriptor_start[device->report_id_index] = i + 1;
217+
218+
// Remember the report id that was assigned.
219+
device->report_id = i + 1;
220+
221+
// Advance to the next free chunk for the next report descriptor.x
208222
report_descriptor_start += device->report_descriptor_length;
209223
}
210224
// Clear the heap pointer to the bytes of the descriptor.
225+
// We don't need it any more and it will get lost when the heap goes away.
211226
device->report_descriptor = NULL;
212227
}
213228
}
@@ -220,11 +235,14 @@ void usb_hid_save_report_descriptor(uint8_t *report_descriptor_space, size_t rep
220235
// Copy the descriptor from the temporary area to a supervisor storage allocation that
221236
// will leave between VM instantiations.
222237
hid_report_descriptor_allocation =
223-
allocate_memory(report_descriptor_length, /*high_address*/ false, /*movable*/ false);
238+
allocate_memory(align32_size(report_descriptor_length),
239+
/*high_address*/ false, /*movable*/ false);
224240
memcpy((uint8_t *) hid_report_descriptor_allocation->ptr, report_descriptor_space, report_descriptor_length);
225241
}
226242

227243
void usb_hid_gc_collect(void) {
244+
gc_collect_ptr(hid_devices_tuple);
245+
228246
// Mark any heap pointers in the static device list as in use.
229247
for (mp_int_t i = 0; i < hid_devices_num; i++) {
230248
gc_collect_ptr(&hid_devices[i]);

shared-module/usb_midi/__init__.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,9 @@ static const mp_rom_obj_tuple_t midi_ports_tuple = {
234234
};
235235

236236
void usb_midi_setup_ports(void) {
237+
// Right now midi_ports_tuple contains no heap objects, but if it does in the future,
238+
// it will need to be protected against gc.
239+
237240
mp_obj_tuple_t *ports = usb_midi_is_enabled ? MP_OBJ_FROM_PTR(&midi_ports_tuple) : mp_const_empty_tuple;
238241
mp_map_lookup(&usb_midi_module_globals.map, MP_ROM_QSTR(MP_QSTR_ports), MP_MAP_LOOKUP)->value =
239242
MP_OBJ_FROM_PTR(ports);

supervisor/shared/usb/tusb_config.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,17 @@ extern "C" {
5959
// DEVICE CONFIGURATION
6060
// --------------------------------------------------------------------+
6161

62+
#if USB_HIGHSPEED
6263
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
64+
#else
65+
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE)
66+
#endif
6367

6468
// Vendor name included in Inquiry response, max 8 bytes
65-
#define CFG_TUD_MSC_VENDOR USB_MANUFACTURER
69+
#define CFG_TUD_MSC_VENDOR USB_MANUFACTURER_8
6670

6771
// Product name included in Inquiry response, max 16 bytes
68-
#define CFG_TUD_MSC_PRODUCT USB_PRODUCT
69-
72+
#define CFG_TUD_MSC_PRODUCT USB_PRODUCT_16
7073
#define CFG_TUD_ENDPOINT0_SIZE 64
7174

7275
// ------------- CLASS -------------//

supervisor/shared/usb/usb_desc.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ static interface_string_t collected_interface_strings[MAX_INTERFACE_STRINGS];
6363
static size_t collected_interface_strings_length;
6464
static uint8_t current_interface_string;
6565

66-
supervisor_allocation *device_descriptor_allocation;
67-
supervisor_allocation *configuration_descriptor_allocation;
68-
supervisor_allocation *string_descriptors_allocation;
66+
static supervisor_allocation *device_descriptor_allocation;
67+
static supervisor_allocation *configuration_descriptor_allocation;
68+
static supervisor_allocation *string_descriptors_allocation;
6969

7070
static const char manufacturer_name[] = USB_MANUFACTURER;
7171
static const char product_name[] = USB_PRODUCT;
@@ -114,7 +114,8 @@ static const uint8_t configuration_descriptor_template[] = {
114114

115115
static void usb_build_device_descriptor(uint16_t vid, uint16_t pid) {
116116
device_descriptor_allocation =
117-
allocate_memory(sizeof(device_descriptor_template), /*high_address*/ false, /*movable*/ false);
117+
allocate_memory(align32_size(sizeof(device_descriptor_template)),
118+
/*high_address*/ false, /*movable*/ false);
118119
uint8_t *device_descriptor = (uint8_t *) device_descriptor_allocation->ptr;
119120
memcpy(device_descriptor, device_descriptor_template, sizeof(device_descriptor_template));
120121

@@ -170,7 +171,8 @@ static void usb_build_configuration_descriptor(void) {
170171

171172
// Now we now how big the configuration descriptor will be, so we can allocate space for it.
172173
configuration_descriptor_allocation =
173-
allocate_memory(total_descriptor_length, /*high_address*/ false, /*movable*/ false);
174+
allocate_memory(align32_size(total_descriptor_length),
175+
/*high_address*/ false, /*movable*/ false);
174176
uint8_t *configuration_descriptor = (uint8_t *) configuration_descriptor_allocation->ptr;
175177

176178
// Copy the template, which is the first part of the descriptor, and fix up its length.
@@ -248,7 +250,7 @@ static void usb_build_interface_string_table(void) {
248250
// Allocate space for the le16 String descriptors.
249251
// Space needed is 2 bytes for String Descriptor header, then 2 bytes for each character
250252
string_descriptors_allocation =
251-
allocate_memory(current_interface_string * 2 + collected_interface_strings_length * 2,
253+
allocate_memory(align32_size(current_interface_string * 2 + collected_interface_strings_length * 2),
252254
/*high_address*/ false, /*movable*/ false);
253255
uint16_t *string_descriptors = (uint16_t *) string_descriptors_allocation->ptr;
254256

@@ -309,7 +311,7 @@ void usb_build_descriptors(void) {
309311
// Invoked when GET DEVICE DESCRIPTOR is received.
310312
// Application return pointer to descriptor
311313
uint8_t const *tud_descriptor_device_cb(void) {
312-
return (uint8_t *) device_descriptor_allocation;
314+
return (uint8_t *) device_descriptor_allocation->ptr;
313315
}
314316

315317
// Invoked when GET CONFIGURATION DESCRIPTOR is received.

supervisor/supervisor.mk

Lines changed: 7 additions & 0 deletions

0 commit comments

Comments
 (0)