From 814ebc62465f9adb429d40b097a93a019dc2dc8f Mon Sep 17 00:00:00 2001 From: Steffen Kreutz Date: Fri, 5 Apr 2024 12:27:22 +0200 Subject: [PATCH 1/3] Make USB MIDI interface names customizable --- shared-bindings/usb_midi/__init__.c | 75 ++++++++++++++++++++++++++--- shared-module/usb_midi/__init__.c | 37 ++++++++++++-- shared-module/usb_midi/__init__.h | 5 ++ 3 files changed, 107 insertions(+), 10 deletions(-) diff --git a/shared-bindings/usb_midi/__init__.c b/shared-bindings/usb_midi/__init__.c index f0e94d62bbcf5..e5ee7b086e2c9 100644 --- a/shared-bindings/usb_midi/__init__.c +++ b/shared-bindings/usb_midi/__init__.c @@ -78,13 +78,76 @@ STATIC mp_obj_t usb_midi_enable(void) { } MP_DEFINE_CONST_FUN_OBJ_0(usb_midi_enable_obj, usb_midi_enable); +STATIC void set_name(mp_obj_t *arg_obj, qstr arg_name, char **custom_name) { + if (*arg_obj == mp_const_none) { + return; + } + + mp_buffer_info_t name; + mp_get_buffer_raise(*arg_obj, &name, MP_BUFFER_READ); + mp_arg_validate_length_range(name.len, 1, 126, arg_name); + + if (*custom_name == NULL) { + *custom_name = port_malloc(sizeof(char) * 128, false); + } + + memcpy(*custom_name, name.buf, name.len); + *custom_name[name.len] = 0; +} + +//| def set_names( +//| self, +//| *, +//| streaming_interface_name: Optional[str] = None, +//| audio_control_interface_name: Optional[str] = None, +//| in_jack_name: Optional[str] = None, +//| out_jack_name: Optional[str] = None +//| ) -> None: +//| """Override the MIDI interface names in the USB Interface Descriptor. +//| +//| ``streaming_interface_name`` must be an ASCII string (or buffer) of at most 126 characters. +//| ``audio_control_interface_name`` must be an ASCII string (or buffer) of at most 126 characters. +//| ``in_jack_name`` must be an ASCII string (or buffer) of at most 126 characters. +//| ``out_jack_name`` must be an ASCII string (or buffer) of at most 126 characters. +//| +//| This method must be called in boot.py to have any effect. +//| +//| Not available on boards without native USB support. +//| """ +//| ... +//| +STATIC mp_obj_t usb_midi_set_names(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + static const mp_arg_t allowed_args[] = { + { MP_QSTR_streaming_interface_name, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, + { MP_QSTR_audio_control_interface_name, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, + { MP_QSTR_in_jack_name, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, + { MP_QSTR_out_jack_name, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, + }; + struct { + mp_arg_val_t streaming_interface_name; + mp_arg_val_t audio_control_interface_name; + mp_arg_val_t in_jack_name; + mp_arg_val_t out_jack_name; + } args; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t *)&args); + + set_name(&(args.streaming_interface_name.u_obj), MP_QSTR_streaming_interface_name, &custom_usb_midi_streaming_interface_name); + set_name(&(args.audio_control_interface_name.u_obj), MP_QSTR_audio_control_interface_name, &custom_usb_midi_audio_control_interface_name); + set_name(&(args.in_jack_name.u_obj), MP_QSTR_in_jack_name, &custom_usb_midi_in_jack_name); + set_name(&(args.out_jack_name.u_obj), MP_QSTR_out_jack_name, &custom_usb_midi_out_jack_name); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(usb_midi_set_names_obj, 0, usb_midi_set_names); + mp_map_elem_t usb_midi_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_usb_midi) }, - { MP_ROM_QSTR(MP_QSTR_disable), MP_OBJ_FROM_PTR(&usb_midi_disable_obj) }, - { MP_ROM_QSTR(MP_QSTR_enable), MP_OBJ_FROM_PTR(&usb_midi_enable_obj) }, - { MP_ROM_QSTR(MP_QSTR_ports), mp_const_empty_tuple }, - { MP_ROM_QSTR(MP_QSTR_PortIn), MP_OBJ_FROM_PTR(&usb_midi_portin_type) }, - { MP_ROM_QSTR(MP_QSTR_PortOut), MP_OBJ_FROM_PTR(&usb_midi_portout_type) }, + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_usb_midi) }, + { MP_ROM_QSTR(MP_QSTR_disable), MP_OBJ_FROM_PTR(&usb_midi_disable_obj) }, + { MP_ROM_QSTR(MP_QSTR_enable), MP_OBJ_FROM_PTR(&usb_midi_enable_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_names), MP_OBJ_FROM_PTR(&usb_midi_set_names_obj) }, + { MP_ROM_QSTR(MP_QSTR_ports), mp_const_empty_tuple }, + { MP_ROM_QSTR(MP_QSTR_PortIn), MP_OBJ_FROM_PTR(&usb_midi_portin_type) }, + { MP_ROM_QSTR(MP_QSTR_PortOut), MP_OBJ_FROM_PTR(&usb_midi_portout_type) }, }; // This isn't const so we can set ports dynamically. diff --git a/shared-module/usb_midi/__init__.c b/shared-module/usb_midi/__init__.c index aca3946b2cddc..e039fac746b6a 100644 --- a/shared-module/usb_midi/__init__.c +++ b/shared-module/usb_midi/__init__.c @@ -177,12 +177,17 @@ size_t usb_midi_descriptor_length(void) { return sizeof(usb_midi_descriptor_template); } -static const char midi_streaming_interface_name[] = USB_INTERFACE_NAME " MIDI"; -static const char midi_audio_control_interface_name[] = USB_INTERFACE_NAME " Audio"; -static const char midi_in_jack_name[] = USB_INTERFACE_NAME " usb_midi.ports[0]"; -static const char midi_out_jack_name[] = USB_INTERFACE_NAME " usb_midi.ports[0]"; +char *custom_usb_midi_streaming_interface_name; +char *custom_usb_midi_audio_control_interface_name; +char *custom_usb_midi_in_jack_name; +char *custom_usb_midi_out_jack_name; size_t usb_midi_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *descriptor_counts, uint8_t *current_interface_string) { + const char *midi_streaming_interface_name; + const char *midi_audio_control_interface_name; + const char *midi_in_jack_name; + const char *midi_out_jack_name; + memcpy(descriptor_buf, usb_midi_descriptor_template, sizeof(usb_midi_descriptor_template)); descriptor_buf[MIDI_AUDIO_CONTROL_INTERFACE_NUMBER_INDEX] = descriptor_counts->current_interface; @@ -200,18 +205,42 @@ size_t usb_midi_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *des descriptor_buf[MIDI_STREAMING_INTERFACE_NUMBER_INDEX_2] = descriptor_counts->current_interface; descriptor_counts->current_interface++; + if (custom_usb_midi_streaming_interface_name == NULL) { + midi_streaming_interface_name = USB_INTERFACE_NAME " MIDI"; + } else { + midi_streaming_interface_name = custom_usb_midi_streaming_interface_name; + } + usb_add_interface_string(*current_interface_string, midi_streaming_interface_name); descriptor_buf[MIDI_STREAMING_INTERFACE_STRING_INDEX] = *current_interface_string; (*current_interface_string)++; + if (custom_usb_midi_audio_control_interface_name == NULL) { + midi_audio_control_interface_name = USB_INTERFACE_NAME " Audio"; + } else { + midi_audio_control_interface_name = custom_usb_midi_audio_control_interface_name; + } + usb_add_interface_string(*current_interface_string, midi_audio_control_interface_name); descriptor_buf[MIDI_AUDIO_CONTROL_INTERFACE_STRING_INDEX] = *current_interface_string; (*current_interface_string)++; + if (custom_usb_midi_in_jack_name == NULL) { + midi_in_jack_name = USB_INTERFACE_NAME " usb_midi.ports[0]"; + } else { + midi_in_jack_name = custom_usb_midi_in_jack_name; + } + usb_add_interface_string(*current_interface_string, midi_in_jack_name); descriptor_buf[MIDI_IN_JACK_STRING_INDEX] = *current_interface_string; (*current_interface_string)++; + if (custom_usb_midi_out_jack_name == NULL) { + midi_out_jack_name = USB_INTERFACE_NAME " usb_midi.ports[0]"; + } else { + midi_out_jack_name = custom_usb_midi_out_jack_name; + } + usb_add_interface_string(*current_interface_string, midi_out_jack_name); descriptor_buf[MIDI_OUT_JACK_STRING_INDEX] = *current_interface_string; (*current_interface_string)++; diff --git a/shared-module/usb_midi/__init__.h b/shared-module/usb_midi/__init__.h index 8cc430efe338e..453d01733ca30 100644 --- a/shared-module/usb_midi/__init__.h +++ b/shared-module/usb_midi/__init__.h @@ -36,4 +36,9 @@ void usb_midi_setup_ports(void); size_t usb_midi_descriptor_length(void); size_t usb_midi_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *descriptor_counts, uint8_t *current_interface_string); +extern char *custom_usb_midi_streaming_interface_name; +extern char *custom_usb_midi_audio_control_interface_name; +extern char *custom_usb_midi_in_jack_name; +extern char *custom_usb_midi_out_jack_name; + #endif /* SHARED_MODULE_USB_MIDI___INIT___H */ From e97ac185d2d32212ecb155aba70fdbff8a6e3689 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sat, 6 Apr 2024 11:33:00 -0400 Subject: [PATCH 2/3] factor out name-setting in usb_midi_set_names() --- shared-bindings/usb_midi/__init__.c | 53 +++++++++++++++-------------- shared-module/usb_midi/__init__.c | 8 ++--- 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/shared-bindings/usb_midi/__init__.c b/shared-bindings/usb_midi/__init__.c index e5ee7b086e2c9..a96236b1fcb6c 100644 --- a/shared-bindings/usb_midi/__init__.c +++ b/shared-bindings/usb_midi/__init__.c @@ -78,23 +78,23 @@ STATIC mp_obj_t usb_midi_enable(void) { } MP_DEFINE_CONST_FUN_OBJ_0(usb_midi_enable_obj, usb_midi_enable); -STATIC void set_name(mp_obj_t *arg_obj, qstr arg_name, char **custom_name) { - if (*arg_obj == mp_const_none) { - return; - } - mp_buffer_info_t name; - mp_get_buffer_raise(*arg_obj, &name, MP_BUFFER_READ); - mp_arg_validate_length_range(name.len, 1, 126, arg_name); +static void set_name(mp_obj_t name_obj, qstr arg_name_qstr, char **custom_name_p) { + if (name_obj != mp_const_none) { + mp_buffer_info_t name; + mp_get_buffer_raise(name_obj, &name, MP_BUFFER_READ); + mp_arg_validate_length_range(name.len, 1, 126, arg_name_qstr); - if (*custom_name == NULL) { - *custom_name = port_malloc(sizeof(char) * 128, false); - } + if (*custom_name_p == NULL) { + *custom_name_p = port_malloc(sizeof(char) * 128, false); + } - memcpy(*custom_name, name.buf, name.len); - *custom_name[name.len] = 0; + memcpy(*custom_name_p, name.buf, name.len); + (*custom_name_p)[name.len] = 0; + } } + //| def set_names( //| self, //| *, @@ -117,24 +117,27 @@ STATIC void set_name(mp_obj_t *arg_obj, qstr arg_name, char **custom_name) { //| ... //| STATIC mp_obj_t usb_midi_set_names(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_streaming_interface_name, ARG_audio_control_interface_name, ARG_in_jack_name, ARG_out_jack_name }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_streaming_interface_name, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, + { MP_QSTR_streaming_interface_name, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, { MP_QSTR_audio_control_interface_name, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, - { MP_QSTR_in_jack_name, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, - { MP_QSTR_out_jack_name, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, + { MP_QSTR_in_jack_name, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, + { MP_QSTR_out_jack_name, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, }; - struct { - mp_arg_val_t streaming_interface_name; - mp_arg_val_t audio_control_interface_name; - mp_arg_val_t in_jack_name; - mp_arg_val_t out_jack_name; - } args; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t *)&args); - set_name(&(args.streaming_interface_name.u_obj), MP_QSTR_streaming_interface_name, &custom_usb_midi_streaming_interface_name); - set_name(&(args.audio_control_interface_name.u_obj), MP_QSTR_audio_control_interface_name, &custom_usb_midi_audio_control_interface_name); - set_name(&(args.in_jack_name.u_obj), MP_QSTR_in_jack_name, &custom_usb_midi_in_jack_name); - set_name(&(args.out_jack_name.u_obj), MP_QSTR_out_jack_name, &custom_usb_midi_out_jack_name); + mp_obj_t streaming_interface_name_obj = args[ARG_streaming_interface_name].u_obj; + set_name(streaming_interface_name_obj, MP_QSTR_streaming_interface_name, &custom_usb_midi_streaming_interface_name); + + mp_obj_t audio_control_interface_name_obj = args[ARG_audio_control_interface_name].u_obj; + set_name(audio_control_interface_name_obj, MP_QSTR_audio_control_interface_name, &custom_usb_midi_audio_control_interface_name); + + mp_obj_t in_jack_name_obj = args[ARG_in_jack_name].u_obj; + set_name(in_jack_name_obj, MP_QSTR_in_jack_name, &custom_usb_midi_in_jack_name); + + mp_obj_t out_jack_name_obj = args[ARG_out_jack_name].u_obj; + set_name(out_jack_name_obj, MP_QSTR_out_jack_name, &custom_usb_midi_out_jack_name); return mp_const_none; } diff --git a/shared-module/usb_midi/__init__.c b/shared-module/usb_midi/__init__.c index e039fac746b6a..9bd9414ca6c4e 100644 --- a/shared-module/usb_midi/__init__.c +++ b/shared-module/usb_midi/__init__.c @@ -177,10 +177,10 @@ size_t usb_midi_descriptor_length(void) { return sizeof(usb_midi_descriptor_template); } -char *custom_usb_midi_streaming_interface_name; -char *custom_usb_midi_audio_control_interface_name; -char *custom_usb_midi_in_jack_name; -char *custom_usb_midi_out_jack_name; +char *custom_usb_midi_streaming_interface_name = NULL; +char *custom_usb_midi_audio_control_interface_name = NULL; +char *custom_usb_midi_in_jack_name = NULL; +char *custom_usb_midi_out_jack_name = NULL; size_t usb_midi_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *descriptor_counts, uint8_t *current_interface_string) { const char *midi_streaming_interface_name; From 9d8eebc65bd3f00102d2d8097737f96a2bd27dab Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sat, 6 Apr 2024 12:28:02 -0400 Subject: [PATCH 3/3] shrink pygamer and pybadge --- ports/atmel-samd/boards/pybadge/mpconfigboard.mk | 2 ++ ports/atmel-samd/boards/pygamer/mpconfigboard.mk | 2 ++ shared-bindings/usb_midi/__init__.c | 8 ++++---- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ports/atmel-samd/boards/pybadge/mpconfigboard.mk b/ports/atmel-samd/boards/pybadge/mpconfigboard.mk index dc72766bae99d..8005146114a47 100644 --- a/ports/atmel-samd/boards/pybadge/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pybadge/mpconfigboard.mk @@ -14,8 +14,10 @@ CIRCUITPY_AESIO = 0 CIRCUITPY_FLOPPYIO = 0 CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_GIFIO = 0 +CIRCUITPY_I2CDISPLAYBUS = 0 CIRCUITPY_JPEGIO = 0 CIRCUITPY_KEYPAD = 1 +CIRCUITPY_PARALLELDISPLAYBUS= 0 CIRCUITPY_STAGE = 1 FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pybadge diff --git a/ports/atmel-samd/boards/pygamer/mpconfigboard.mk b/ports/atmel-samd/boards/pygamer/mpconfigboard.mk index 3f7e2e25ffa35..5149dda508fb4 100644 --- a/ports/atmel-samd/boards/pygamer/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pygamer/mpconfigboard.mk @@ -14,8 +14,10 @@ CIRCUITPY_AESIO = 0 CIRCUITPY_FLOPPYIO = 0 CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_GIFIO = 0 +CIRCUITPY_I2CDISPLAYBUS = 0 CIRCUITPY_JPEGIO = 0 CIRCUITPY_KEYPAD = 1 +CIRCUITPY_PARALLELDISPLAYBUS= 0 CIRCUITPY_STAGE = 1 FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pygamer diff --git a/shared-bindings/usb_midi/__init__.c b/shared-bindings/usb_midi/__init__.c index a96236b1fcb6c..134ba26f1334d 100644 --- a/shared-bindings/usb_midi/__init__.c +++ b/shared-bindings/usb_midi/__init__.c @@ -105,10 +105,10 @@ static void set_name(mp_obj_t name_obj, qstr arg_name_qstr, char **custom_name_p //| ) -> None: //| """Override the MIDI interface names in the USB Interface Descriptor. //| -//| ``streaming_interface_name`` must be an ASCII string (or buffer) of at most 126 characters. -//| ``audio_control_interface_name`` must be an ASCII string (or buffer) of at most 126 characters. -//| ``in_jack_name`` must be an ASCII string (or buffer) of at most 126 characters. -//| ``out_jack_name`` must be an ASCII string (or buffer) of at most 126 characters. +//| :param Optional[str] streaming_interface_name: an ASCII string (or buffer) of at most 126 characters, or ``None`` to use the default name. +//| :param Optional[str] audio_control_interface_name: an ASCII string (or buffer) of at most 126 characters, or ``None`` to use the default name. +//| :param Optional[str] in_jack_name: an ASCII string (or buffer) of at most 126 characters, or ``None`` to use the default name. +//| :param Optional[str] out_jack_name: an ASCII string (or buffer) of at most 126 characters, or ``None`` to use the default name. //| //| This method must be called in boot.py to have any effect. //|