Skip to content

Commit b23ec04

Browse files
committed
Add superisor.set_usb_descriptor_overrides() function
1 parent 7ad35bf commit b23ec04

File tree

4 files changed

+126
-4
lines changed

4 files changed

+126
-4
lines changed

locale/circuitpython.pot

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4341,6 +4341,10 @@ msgstr ""
43414341
msgid "string not supported; use bytes or bytearray"
43424342
msgstr ""
43434343

4344+
#: shared-bindings/supervisor/__init__.c
4345+
msgid "string too long"
4346+
msgstr ""
4347+
43444348
#: extmod/moductypes.c
43454349
msgid "struct: can't index"
43464350
msgstr ""
@@ -4591,6 +4595,10 @@ msgstr ""
45914595
msgid "value_count must be > 0"
45924596
msgstr ""
45934597

4598+
#: shared-bindings/supervisor/__init__.c
4599+
msgid "vid or pid out of range"
4600+
msgstr ""
4601+
45944602
#: ports/espressif/common-hal/watchdog/WatchDogTimer.c
45954603
msgid "watchdog not initialized"
45964604
msgstr ""

shared-bindings/supervisor/__init__.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "supervisor/shared/traceback.h"
3939
#include "supervisor/shared/translate.h"
4040
#include "supervisor/shared/workflow.h"
41+
#include "supervisor/shared/usb/usb_desc.h"
4142

4243
#include "shared-bindings/microcontroller/__init__.h"
4344
#include "shared-bindings/supervisor/__init__.h"
@@ -311,6 +312,63 @@ STATIC mp_obj_t supervisor_reset_terminal(mp_obj_t x_pixels, mp_obj_t y_pixels)
311312
}
312313
MP_DEFINE_CONST_FUN_OBJ_2(supervisor_reset_terminal_obj, supervisor_reset_terminal);
313314

315+
//| def set_usb_descriptor_overrides(manufacturer: Optional[str] = None, product: Optional[str] = None, vid: Optional[int] = None, pid: Optional[int] = None) -> None:
316+
//| """Override constants in the USB Device Descriptor.
317+
//|
318+
//| Any omitted arguments will be left at their current or default values.
319+
//| This method must be called in boot.py to have any effect."""
320+
//| ...
321+
//|
322+
STATIC mp_obj_t supervisor_set_usb_descriptor_overrides(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
323+
static const mp_arg_t allowed_args[] = {
324+
{ MP_QSTR_manufacturer, MP_ARG_OBJ, {.u_rom_obj = mp_const_none} },
325+
{ MP_QSTR_product, MP_ARG_OBJ, {.u_rom_obj = mp_const_none} },
326+
{ MP_QSTR_vid, MP_ARG_INT, {.u_int = -1} },
327+
{ MP_QSTR_pid, MP_ARG_INT, {.u_int = -1} },
328+
};
329+
struct {
330+
mp_arg_val_t manufacturer;
331+
mp_arg_val_t product;
332+
mp_arg_val_t vid;
333+
mp_arg_val_t pid;
334+
} args;
335+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t *)&args);
336+
337+
if (!mp_obj_is_str_or_bytes(args.manufacturer.u_obj) && args.manufacturer.u_obj != mp_const_none) {
338+
mp_raise_TypeError(translate("argument has wrong type"));
339+
}
340+
if (!mp_obj_is_str_or_bytes(args.product.u_obj) && args.product.u_obj != mp_const_none) {
341+
mp_raise_TypeError(translate("argument has wrong type"));
342+
}
343+
344+
const char *manufacturer = NULL;
345+
const char *product = NULL;
346+
347+
size_t len;
348+
if (args.manufacturer.u_obj != mp_const_none) {
349+
manufacturer = mp_obj_str_get_data(args.manufacturer.u_obj, &len);
350+
if (len > 126) {
351+
mp_raise_ValueError(translate("string too long"));
352+
}
353+
}
354+
if (args.product.u_obj != mp_const_none) {
355+
product = mp_obj_str_get_data(args.product.u_obj, &len);
356+
if (len > 126) {
357+
mp_raise_ValueError(translate("string too long"));
358+
}
359+
}
360+
if (args.vid.u_int < -1 || args.vid.u_int >= (1 << 16)) {
361+
mp_raise_ValueError(translate("vid or pid out of range"));
362+
}
363+
if (args.pid.u_int < -1 || args.pid.u_int >= (1 << 16)) {
364+
mp_raise_ValueError(translate("vid or pid out of range"));
365+
}
366+
367+
usb_set_descriptor_overrides(manufacturer, product, args.vid.u_int, args.pid.u_int);
368+
return mp_const_none;
369+
}
370+
MP_DEFINE_CONST_FUN_OBJ_KW(supervisor_set_usb_descriptor_overrides_obj, 0, supervisor_set_usb_descriptor_overrides);
371+
314372
STATIC const mp_rom_map_elem_t supervisor_module_globals_table[] = {
315373
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_supervisor) },
316374
{ MP_ROM_QSTR(MP_QSTR_enable_autoreload), MP_ROM_PTR(&supervisor_enable_autoreload_obj) },
@@ -325,6 +383,7 @@ STATIC const mp_rom_map_elem_t supervisor_module_globals_table[] = {
325383
{ MP_ROM_QSTR(MP_QSTR_get_previous_traceback), MP_ROM_PTR(&supervisor_get_previous_traceback_obj) },
326384
{ MP_ROM_QSTR(MP_QSTR_disable_ble_workflow), MP_ROM_PTR(&supervisor_disable_ble_workflow_obj) },
327385
{ MP_ROM_QSTR(MP_QSTR_reset_terminal), MP_ROM_PTR(&supervisor_reset_terminal_obj) },
386+
{ MP_ROM_QSTR(MP_QSTR_set_usb_descriptor_overrides), MP_ROM_PTR(&supervisor_set_usb_descriptor_overrides_obj) },
328387
};
329388

330389
STATIC MP_DEFINE_CONST_DICT(supervisor_module_globals, supervisor_module_globals_table);

supervisor/shared/usb/usb_desc.c

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "supervisor/memory.h"
3232
#include "supervisor/shared/safe_mode.h"
3333
#include "supervisor/usb.h"
34+
#include "supervisor/shared/usb/usb_desc.h"
3435

3536
#if CIRCUITPY_USB_CDC
3637
#include "shared-bindings/usb_cdc/__init__.h"
@@ -68,8 +69,10 @@ static supervisor_allocation *device_descriptor_allocation;
6869
static supervisor_allocation *configuration_descriptor_allocation;
6970
static supervisor_allocation *string_descriptors_allocation;
7071

71-
static const char manufacturer_name[] = USB_MANUFACTURER;
72-
static const char product_name[] = USB_PRODUCT;
72+
static char manufacturer_name[127] = USB_MANUFACTURER;
73+
static char product_name[127] = USB_PRODUCT;
74+
static uint16_t vid = USB_VID;
75+
static uint16_t pid = USB_PID;
7376

7477
// Serial number string is UID length * 2 (2 nibbles per byte) + 1 byte for null termination.
7578
static char serial_number_hex_string[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH * 2 + 1];
@@ -113,7 +116,7 @@ static const uint8_t configuration_descriptor_template[] = {
113116
0x32, // 8 bMaxPower 100mA
114117
};
115118

116-
static void usb_build_device_descriptor(uint16_t vid, uint16_t pid) {
119+
static void usb_build_device_descriptor() {
117120
device_descriptor_allocation =
118121
allocate_memory(align32_size(sizeof(device_descriptor_template)),
119122
/*high_address*/ false, /*movable*/ false);
@@ -336,11 +339,29 @@ void usb_build_descriptors(void) {
336339
current_interface_string = 1;
337340
collected_interface_strings_length = 0;
338341

339-
usb_build_device_descriptor(USB_VID, USB_PID);
342+
usb_build_device_descriptor();
340343
usb_build_configuration_descriptor();
341344
usb_build_interface_string_table();
342345
}
343346

347+
void usb_set_descriptor_overrides(const char *new_manufacturer, const char *new_product, mp_int_t new_vid, mp_int_t new_pid) {
348+
if (new_manufacturer != NULL && strlen(new_manufacturer) < sizeof(manufacturer_name)) {
349+
memcpy(manufacturer_name, new_manufacturer, strlen(new_manufacturer)+1);
350+
}
351+
352+
if (new_product != NULL && strlen(new_product) < sizeof(product_name)) {
353+
memcpy(product_name, new_product, strlen(new_product)+1);
354+
}
355+
356+
if (new_vid >= 0) {
357+
vid = new_vid;
358+
}
359+
360+
if (new_pid >= 0) {
361+
pid = new_pid;
362+
}
363+
}
364+
344365
// Invoked when GET DEVICE DESCRIPTOR is received.
345366
// Application return pointer to descriptor
346367
uint8_t const *tud_descriptor_device_cb(void) {

supervisor/shared/usb/usb_desc.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#ifndef MICROPY_INCLUDED_SUPERVISOR_USB_DESC_H
28+
#define MICROPY_INCLUDED_SUPERVISOR_USB_DESC_H
29+
30+
#include "py/obj.h"
31+
32+
void usb_set_descriptor_overrides(const char *new_manufacturer, const char *new_product, mp_int_t new_vid, mp_int_t new_pid);
33+
34+
#endif // MICROPY_INCLUDED_SUPERVISOR_USB_DESC_H

0 commit comments

Comments
 (0)