count in/out endpoints; allow more usb modules on low-endpoint boards

This commit is contained in:
Dan Halbert 2021-05-13 21:49:04 -04:00
parent 0651ef17dd
commit fa6c06fb38
35 changed files with 200 additions and 124 deletions

View File

@ -4538,7 +4538,7 @@ msgstr ""
#~ msgstr "Berjalan di mode aman(safe mode)! Auto-reload tidak aktif.\n"
#~ msgid "Running in safe mode! Not running saved code.\n"
#~ msgstr ""
#~ msgstr "Berjalan di mode aman(safe mode)! Tidak menjalankan kode yang disimpan.\n"
#~ "Berjalan di mode aman(safe mode)! tidak menjalankan kode yang tersimpan.\n"
#~ msgid "'async for' or 'async with' outside async function"

View File

@ -732,8 +732,8 @@ msgstr ""
"zu verlassen.\n"
#: supervisor/shared/safe_mode.c
msgid "CircuitPython was unable to allocate the heap.\n"
msgstr "CircuitPython war es nicht möglich heap-Speicher zu allozieren.\n"
msgid "CircuitPython was unable to allocate the heap."
msgstr "CircuitPython war es nicht möglich heap-Speicher zu allozieren."
#: shared-module/bitbangio/SPI.c
msgid "Clock pin init failed."

View File

@ -729,8 +729,8 @@ msgstr ""
"boot. Press again to exit safe mode.\n"
#: supervisor/shared/safe_mode.c
msgid "CircuitPython was unable to allocate the heap.\n"
msgstr "CircuitPython was unable to allocate the heap.\n"
msgid "CircuitPython was unable to allocate the heap."
msgstr "CircuitPython was unable to allocate the heap."
#: shared-module/bitbangio/SPI.c
msgid "Clock pin init failed."

View File

@ -738,8 +738,8 @@ msgstr ""
"durante el arranque. Presione nuevamente para salir del modo seguro.\n"
#: supervisor/shared/safe_mode.c
msgid "CircuitPython was unable to allocate the heap.\n"
msgstr "CircuitPython no puedo encontrar el montículo.\n"
msgid "CircuitPython was unable to allocate the heap."
msgstr "CircuitPython no puedo encontrar el montículo."
#: shared-module/bitbangio/SPI.c
msgid "Clock pin init failed."
@ -4777,7 +4777,7 @@ msgstr "zi debe ser una forma (n_section,2)"
#~ msgstr "Ejecutando en modo seguro! La auto-recarga esta deshabilitada.\n"
#~ msgid "Running in safe mode! Not running saved code.\n"
#~ msgstr ""
#~ msgstr "Ejecutando en modo seguro! No ejecutando el código almacenado.\n"
#~ "Ejecutando en modo seguro! No se esta ejecutando el código guardado.\n"
#~ msgid "__init__() should return None, not '%s'"

View File

@ -745,8 +745,8 @@ msgstr ""
"mode sans échec.\n"
#: supervisor/shared/safe_mode.c
msgid "CircuitPython was unable to allocate the heap.\n"
msgstr "CircuitPython n'as pu faire l'allocation de la pile.\n"
msgid "CircuitPython was unable to allocate the heap."
msgstr "CircuitPython n'as pu faire l'allocation de la pile."
#: shared-module/bitbangio/SPI.c
msgid "Clock pin init failed."

View File

@ -716,7 +716,7 @@ msgid ""
msgstr ""
#: supervisor/shared/safe_mode.c
msgid "CircuitPython was unable to allocate the heap.\n"
msgid "CircuitPython was unable to allocate the heap."
msgstr ""
#: shared-module/bitbangio/SPI.c

View File

@ -727,8 +727,8 @@ msgstr ""
"度押すとセーフモードを終了します。\n"
#: supervisor/shared/safe_mode.c
msgid "CircuitPython was unable to allocate the heap.\n"
msgstr "CircuitPythonはヒープを確保できませんでした\n"
msgid "CircuitPython was unable to allocate the heap."
msgstr "CircuitPythonはヒープを確保できませんでした"
#: shared-module/bitbangio/SPI.c
msgid "Clock pin init failed."
@ -1966,8 +1966,8 @@ msgid "Row entry must be digitalio.DigitalInOut"
msgstr "Rowの各要素は digitalio.DigitalInOut でなければなりません"
#: main.c
msgid "Running in safe mode! "
msgstr "セーフモードで実行中! "
msgid "Running in safe mode! Not running saved code.\n"
msgstr "セーフモードで実行中! 保存されたコードは実行していません。\n"
#: shared-module/sdcardio/SDCard.c
msgid "SD card CSD format not supported"

View File

@ -725,8 +725,8 @@ msgstr ""
"het opstarten. Druk nogmaals om veilige modus te verlaten\n"
#: supervisor/shared/safe_mode.c
msgid "CircuitPython was unable to allocate the heap.\n"
msgstr "CircuitPython kon het heap geheugen niet toewijzen.\n"
msgid "CircuitPython was unable to allocate the heap."
msgstr "CircuitPython kon het heap geheugen niet toewijzen."
#: shared-module/bitbangio/SPI.c
msgid "Clock pin init failed."

View File

@ -725,8 +725,8 @@ msgstr ""
"przycisk resetowania. Naciśnij ponownie, aby wyjść z trybu awaryjnego.\n"
#: supervisor/shared/safe_mode.c
msgid "CircuitPython was unable to allocate the heap.\n"
msgstr "CircuitPython nie mógł przydzielić sterty.\n"
msgid "CircuitPython was unable to allocate the heap."
msgstr "CircuitPython nie mógł przydzielić sterty."
#: shared-module/bitbangio/SPI.c
msgid "Clock pin init failed."

View File

@ -743,8 +743,8 @@ msgstr ""
"de segurança.\n"
#: supervisor/shared/safe_mode.c
msgid "CircuitPython was unable to allocate the heap.\n"
msgstr "O CircuitPython não conseguiu alocar o heap.\n"
msgid "CircuitPython was unable to allocate the heap."
msgstr "O CircuitPython não conseguiu alocar o heap."
#: shared-module/bitbangio/SPI.c
msgid "Clock pin init failed."
@ -4818,7 +4818,7 @@ msgstr "zi deve estar na forma (n_section, 2)"
#~ msgstr "Rodando em modo seguro! Atualização automática está desligada.\n"
#~ msgid "Running in safe mode! Not running saved code.\n"
#~ msgstr "Rodando em modo seguro! Não está executando o código salvo.\n"
#~ msgstr "Rodando em modo seguro! O código salvo não está em execução.\n"
#~ msgid "__init__() should return None, not '%s'"
#~ msgstr "O __init__() deve retornar Nenhum, não '%s'"

View File

@ -731,8 +731,8 @@ msgstr ""
"under start. Tryck igen för att lämna säkert läge.\n"
#: supervisor/shared/safe_mode.c
msgid "CircuitPython was unable to allocate the heap.\n"
msgstr "CircuitPython kunde inte allokera heap.\n"
msgid "CircuitPython was unable to allocate the heap."
msgstr "CircuitPython kunde inte allokera heap."
#: shared-module/bitbangio/SPI.c
msgid "Clock pin init failed."

View File

@ -732,8 +732,8 @@ msgstr ""
"chóng zhì ànniǔ. Zài àn yīcì tuìchū ānquán móshì.\n"
#: supervisor/shared/safe_mode.c
msgid "CircuitPython was unable to allocate the heap.\n"
msgstr "CircuitPython wúfǎ fēnpèi duī.\n"
msgid "CircuitPython was unable to allocate the heap."
msgstr "CircuitPython wúfǎ fēnpèi duī."
#: shared-module/bitbangio/SPI.c
msgid "Clock pin init failed."

View File

@ -21,7 +21,7 @@ endif
INTERNAL_LIBM = 1
# Number of USB endpoint pairs.
USB_NUM_EP = 8
USB_NUM_ENDPOINT_PAIRS = 8
CIRCUITPY_ROTARYIO_SOFTENCODER = 1

View File

@ -1,7 +1,7 @@
USB_HIGHSPEED = 1
# Number of USB endpoint pairs.
USB_NUM_EP = 6
USB_NUM_ENDPOINT_PAIRS = 6
# Define an equivalent for MICROPY_LONGINT_IMPL, to pass to $(MPY-TOOL) in py/mkrules.mk
# $(MPY-TOOL) needs to know what kind of longint to use (if any) to freeze long integers.

View File

@ -27,11 +27,6 @@ CIRCUITPY_ROTARYIO = 1
CIRCUITPY_NVM = 1
CIRCUITPY_PS2IO ?= 1
CIRCUITPY_TOUCHIO_USE_NATIVE ?= 1
# We don't have enough endpoints to include MIDI.
CIRCUITPY_USB_MIDI ?= 0
CIRCUITPY_USB_HID ?= 1
# We have borrowed the VENDOR nomenclature from tinyusb. VENDOR AKA WEBUSB
CIRCUITPY_USB_VENDOR ?= 0
CIRCUITPY_WIFI = 1
CIRCUITPY_WATCHDOG ?= 1
@ -39,4 +34,14 @@ CIRCUITPY_ESPIDF = 1
CIRCUITPY_MODULE ?= none
USB_NUM_EP = 5
# From the ESP32-S2 datasheet:
#
# Endpoint number 0 always present (bi-directional, consisting of EP0 IN and EP0 OUT)
# Six additional endpoints (endpoint numbers 1 to 6), configurable as IN or OUT
# Maximum of five IN endpoints concurrently active at any time (including EP0 IN)
#
# Due to the limited number of endpoints, some USB devices will be off by default.
# For instance MIDI is available, but the device is turned off. It can be turned on
# only if something else is turned off, such as HID.
USB_NUM_ENDPOINT_PAIRS = 7
USB_NUM_IN_ENDPOINTS = 5

View File

@ -7,7 +7,7 @@ MPY_TOOL_LONGINT_IMPL = -mlongint-impl=mpz
INTERNAL_LIBM = 1
# Number of USB endpoint pairs.
USB_NUM_EP = 16
USB_NUM_ENDPOINT_PAIRS = 16
# Longints can be implemented as mpz, as longlong, or not
LONGINT_IMPL = MPZ

View File

@ -17,7 +17,7 @@ INTERNAL_LIBM = 1
USB_HIGHSPEED = 1
# Number of USB endpoint pairs.
USB_NUM_EP = 8
USB_NUM_ENDPOINT_PAIRS = 8
INTERNAL_FLASH_FILESYSTEM = 1

View File

@ -10,7 +10,7 @@ MPY_TOOL_LONGINT_IMPL = -mlongint-impl=mpz
INTERNAL_LIBM = 1
# Number of USB endpoint pairs.
USB_NUM_EP = 8
USB_NUM_ENDPOINT_PAIRS = 8
# All nRF ports have longints.
LONGINT_IMPL = MPZ

View File

@ -49,6 +49,6 @@ CIRCUITPY_AUDIOMIXER = 1
INTERNAL_LIBM = 1
# Number of USB endpoint pairs.
USB_NUM_EP = 8
USB_NUM_ENDPOINT_PAIRS = 8
INTERNAL_FLASH_FILESYSTEM = 1

View File

@ -7,7 +7,7 @@ ifeq ($(MCU_VARIANT),$(filter $(MCU_VARIANT),STM32F405xx STM32F407xx))
CIRCUITPY_FRAMEBUFFERIO ?= 1
CIRCUITPY_SDIOIO ?= 1
# Number of USB endpoint pairs.
USB_NUM_EP = 4
USB_NUM_ENDPOINT_PAIRS = 4
endif
ifeq ($(MCU_SERIES),F4)
@ -24,10 +24,7 @@ ifeq ($(MCU_SERIES),F4)
CIRCUITPY_NVM ?= 0
CIRCUITPY_ROTARYIO ?= 0
CIRCUITPY_RTC ?= 0
CIRCUITPY_USB_MIDI ?= 0
CIRCUITPY_USB_HID ?= 0
USB_NUM_EP = 4
USB_NUM_ENDPOINT_PAIRS = 4
endif
ifeq ($(MCU_SERIES),H7)
@ -44,10 +41,8 @@ ifeq ($(MCU_SERIES),H7)
CIRCUITPY_PWMIO ?= 0
CIRCUITPY_ROTARYIO ?= 0
CIRCUITPY_RTC ?= 0
CIRCUITPY_USB_HID ?= 0
CIRCUITPY_USB_MIDI ?= 0
USB_NUM_EP = 9
USB_NUM_ENDPOINT_PAIRS = 9
endif
ifeq ($(MCU_SERIES),F7)
@ -62,8 +57,6 @@ ifeq ($(MCU_SERIES),F7)
CIRCUITPY_NVM ?= 0
CIRCUITPY_ROTARYIO ?= 0
CIRCUITPY_RTC ?= 0
CIRCUITPY_USB_HID ?= 0
CIRCUITPY_USB_MIDI ?= 0
USB_NUM_EP = 6
USB_NUM_ENDPOINT_PAIRS = 6
endif

View File

@ -338,8 +338,18 @@ CFLAGS += -DCIRCUITPY_UHEAP=$(CIRCUITPY_UHEAP)
CIRCUITPY_USB ?= 1
CFLAGS += -DCIRCUITPY_USB=$(CIRCUITPY_USB)
# Compute this value once, so the shell command is not reinvoked many times.
USB_NUM_EP_8_OR_GREATER := $(shell expr $(USB_NUM_EP) '>=' 8)
# Compute these value once, so the shell command is not reinvoked many times.
USB_NUM_ENDPOINT_PAIRS_5_OR_GREATER := $(shell expr $(USB_NUM_ENDPOINT_PAIRS) '>=' 5)
USB_NUM_ENDPOINT_PAIRS_8_OR_GREATER := $(shell expr $(USB_NUM_ENDPOINT_PAIRS) '>=' 8)
# Some chips may not support the same number of IN or OUT endpoints as pairs.
# For instance, the ESP32-S2 only supports 5 IN endpoints at once, even though
# it has 7 endpoint pairs.
USB_NUM_IN_ENDPOINTS ?= $(USB_NUM_ENDPOINT_PAIRS)
CFLAGS += -DUSB_NUM_IN_ENDPOINTS=$(USB_NUM_IN_ENDPOINTS)
USB_NUM_OUT_ENDPOINTS ?= $(USB_NUM_ENDPOINT_PAIRS)
CFLAGS += -DUSB_NUM_OUT_ENDPOINTS=$(USB_NUM_OUT_ENDPOINTS)
CIRCUITPY_USB_CDC ?= 1
CFLAGS += -DCIRCUITPY_USB_CDC=$(CIRCUITPY_USB_CDC)
@ -348,15 +358,16 @@ CFLAGS += -DCIRCUITPY_USB_CDC_CONSOLE_ENABLED_DEFAULT=$(CIRCUITPY_USB_CDC_CONSOL
CIRCUITPY_USB_CDC_DATA_ENABLED_DEFAULT ?= 0
CFLAGS += -DCIRCUITPY_USB_CDC_DATA_ENABLED_DEFAULT=$(CIRCUITPY_USB_CDC_DATA_ENABLED_DEFAULT)
# HID is available by default, but is not turned on if there are fewer than 5 endpoints.
CIRCUITPY_USB_HID ?= 1
CFLAGS += -DCIRCUITPY_USB_HID=$(CIRCUITPY_USB_HID)
CIRCUITPY_USB_HID_ENABLED_DEFAULT ?= $(CIRCUITPY_USB_HID)
CIRCUITPY_USB_HID_ENABLED_DEFAULT ?= $(USB_NUM_ENDPOINT_PAIRS_5_OR_GREATER)
CFLAGS += -DCIRCUITPY_USB_HID_ENABLED_DEFAULT=$(CIRCUITPY_USB_HID_ENABLED_DEFAULT)
# MIDI is usually available if there are at least 8 endpoints.
CIRCUITPY_USB_MIDI ?= $(USB_NUM_EP_8_OR_GREATER)
# MIDI is available by default, but is not turned on if there are fewer than 8 endpoints.
CIRCUITPY_USB_MIDI ?= 1
CFLAGS += -DCIRCUITPY_USB_MIDI=$(CIRCUITPY_USB_MIDI)
CIRCUITPY_USB_MIDI_ENABLED_DEFAULT ?= $(CIRCUITPY_USB_MIDI)
CIRCUITPY_USB_MIDI_ENABLED_DEFAULT ?= $(USB_NUM_ENDPOINT_PAIRS_8_OR_GREATER)
CFLAGS += -DCIRCUITPY_USB_MIDI_ENABLED_DEFAULT=$(CIRCUITPY_USB_MIDI_ENABLED_DEFAULT)
CIRCUITPY_USB_MSC ?= 1
@ -370,10 +381,10 @@ CFLAGS += -DCIRCUITPY_USB_MSC_ENABLED_DEFAULT=$(CIRCUITPY_USB_MSC_ENABLED_DEFAUL
CIRCUITPY_USB_VENDOR ?= 0
CFLAGS += -DCIRCUITPY_USB_VENDOR=$(CIRCUITPY_USB_VENDOR)
ifndef USB_NUM_EP
$(error "USB_NUM_EP (number of USB endpoint pairs)must be defined")
ifndef USB_NUM_ENDPOINT_PAIRS
$(error "USB_NUM_ENDPOINT_PAIRS (number of USB endpoint pairs)must be defined")
endif
CFLAGS += -DUSB_NUM_EP=$(USB_NUM_EP)
CFLAGS += -DUSB_NUM_ENDPOINT_PAIRS=$(USB_NUM_ENDPOINT_PAIRS)
# For debugging.
CIRCUITPY_USTACK ?= 0

View File

@ -176,7 +176,13 @@ MP_DEFINE_CONST_FUN_OBJ_0(storage_disable_usb_drive_obj, storage_disable_usb_dri
//| """Enabled presenting ``CIRCUITPY`` as a USB mass storage device.
//| By default, the device is enabled and ``CIRCUITPY`` is visible,
//| so you do not normally need to call this function.
//| Can be called in ``boot.py``, before USB is connected."""
//| Can be called in ``boot.py``, before USB is connected.
//|
//| If you enable too many devices at once, you will run out of USB endpoints.
//| The number of available endpoints varies by microcontroller.
//| CircuitPython will go into safe mode after running boot.py to inform you if
//| not enough endpoints are available.
//| """
//| ...
//|
STATIC mp_obj_t storage_enable_usb_drive(void) {

View File

@ -82,7 +82,13 @@ MP_DEFINE_CONST_FUN_OBJ_0(usb_cdc_disable_obj, usb_cdc_disable);
//| :param console bool: Enable or disable the `console` USB serial device.
//| True to enable; False to disable. Enabled by default.
//| :param data bool: Enable or disable the `data` USB serial device.
//| True to enable; False to disable. *Disabled* by default."""
//| True to enable; False to disable. *Disabled* by default.
//|
//| If you enable too many devices at once, you will run out of USB endpoints.
//| The number of available endpoints varies by microcontroller.
//| CircuitPython will go into safe mode after running boot.py to inform you if
//| not enough endpoints are available.
//| """
//| ...
//|
STATIC mp_obj_t usb_cdc_enable(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {

View File

@ -37,12 +37,21 @@
//|
//| devices: Tuple[Device, ...]
//| """Tuple of all active HID device interfaces."""
//| """Tuple of all active HID device interfaces.
//| The default set of devices is ``Device.KEYBOARD, Device.MOUSE, Device.CONSUMER_CONTROL``,
//| On boards where `usb_hid` is disabled by default, `devices` is an empty tuple.
//| """
//|
//| def disable() -> None:
//| """Do not present any USB HID devices to the host computer.
//| Can be called in ``boot.py``, before USB is connected."""
//| Can be called in ``boot.py``, before USB is connected.
//| The HID composite device is normally enabled by default,
//| but on some boards with limited endpoints, including STM32F4,
//| it is disabled by default. You must turn off another USB device such
//| as `usb_cdc` or `storage` to free up endpoints for use by `usb_hid`.
//| """
//|
STATIC mp_obj_t usb_hid_disable(void) {
if (!common_hal_usb_hid_disable()) {
mp_raise_RuntimeError(translate("Cannot change USB devices now"));
@ -59,6 +68,11 @@ MP_DEFINE_CONST_FUN_OBJ_0(usb_hid_disable_obj, usb_hid_disable);
//| If `devices` is empty, HID is disabled. The order of the ``Devices``
//| may matter to the host. For instance, for MacOS, put the mouse device
//| before any Gamepad or Digitizer HID device or else it will not work.
//|
//| If you enable too many devices at once, you will run out of USB endpoints.
//| The number of available endpoints varies by microcontroller.
//| CircuitPython will go into safe mode after running boot.py to inform you if
//| not enough endpoints are available.
//| """
//| ...
//|

View File

@ -45,7 +45,8 @@
//| def disable() -> None:
//| """Disable presenting a USB MIDI device to the host.
//| The device is normally enabled by default.
//| The device is normally enabled by default, but on some boards with limited endpoints
//| including ESP32-S2 and certain STM boards, it is disabled by default.
//| Can be called in ``boot.py``, before USB is connected."""
//| ...
//|
@ -60,7 +61,13 @@ MP_DEFINE_CONST_FUN_OBJ_0(usb_midi_disable_obj, usb_midi_disable);
//| def enable() -> None:
//| """Enable presenting a USB MIDI device to the host.
//| The device is enabled by default, so you do not normally need to call this function.
//| Can be called in ``boot.py``, before USB is connected."""
//| Can be called in ``boot.py``, before USB is connected.
//|
//| If you enable too many devices at once, you will run out of USB endpoints.
//| The number of available endpoints varies by microcontroller.
//| CircuitPython will go into safe mode after running boot.py to inform you if
//| not enough endpoints are available.
//| """
//| ...
//|
STATIC mp_obj_t usb_midi_enable(void) {

View File

@ -93,14 +93,18 @@ size_t storage_usb_descriptor_length(void) {
static const char storage_interface_name[] = USB_INTERFACE_NAME " Mass Storage";
size_t storage_usb_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interface, uint8_t *current_endpoint, uint8_t *current_interface_string) {
size_t storage_usb_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *descriptor_counts, uint8_t *current_interface_string) {
memcpy(descriptor_buf, usb_msc_descriptor_template, sizeof(usb_msc_descriptor_template));
descriptor_buf[MSC_INTERFACE_INDEX] = *current_interface;
(*current_interface)++;
descriptor_buf[MSC_INTERFACE_INDEX] = descriptor_counts->current_interface;
descriptor_counts->current_interface++;
descriptor_buf[MSC_IN_ENDPOINT_INDEX] = 0x80 | (USB_MSC_EP_NUM_IN ? USB_MSC_EP_NUM_IN : *current_endpoint);
descriptor_buf[MSC_OUT_ENDPOINT_INDEX] = USB_MSC_EP_NUM_OUT ? USB_MSC_EP_NUM_OUT : *current_endpoint;
(*current_endpoint)++;
descriptor_buf[MSC_IN_ENDPOINT_INDEX] =
0x80 | (USB_MSC_EP_NUM_IN ? USB_MSC_EP_NUM_IN : descriptor_counts->current_endpoint);
descriptor_counts->num_in_endpoints++;
descriptor_buf[MSC_OUT_ENDPOINT_INDEX] =
USB_MSC_EP_NUM_OUT ? USB_MSC_EP_NUM_OUT : descriptor_counts->current_endpoint;
descriptor_counts->num_out_endpoints++;
descriptor_counts->current_endpoint++;
usb_add_interface_string(*current_interface_string, storage_interface_name);
descriptor_buf[MSC_INTERFACE_STRING_INDEX] = *current_interface_string;

View File

@ -28,12 +28,13 @@
#define SHARED_MODULE_STORAGE___INIT___H
#include "py/mpconfig.h"
#include "supervisor/usb.h"
#if CIRCUITPY_USB
bool storage_usb_enabled(void);
void storage_usb_set_defaults(void);
size_t storage_usb_descriptor_length(void);
size_t storage_usb_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interface, uint8_t *current_endpoint, uint8_t *current_interface_string);
size_t storage_usb_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *descriptor_counts, uint8_t *current_interface_string);
#endif
#endif // SHARED_MODULE_STORAGE___INIT___H

View File

@ -173,37 +173,39 @@ size_t usb_cdc_descriptor_length(void) {
return sizeof(usb_cdc_descriptor_template);
}
size_t usb_cdc_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interface, uint8_t *current_endpoint, uint8_t *current_interface_string, bool console) {
size_t usb_cdc_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *descriptor_counts, uint8_t *current_interface_string, bool console) {
memcpy(descriptor_buf, usb_cdc_descriptor_template, sizeof(usb_cdc_descriptor_template));
// Store comm interface number.
descriptor_buf[CDC_FIRST_INTERFACE_INDEX] = *current_interface;
descriptor_buf[CDC_COMM_INTERFACE_INDEX] = *current_interface;
descriptor_buf[CDC_UNION_MASTER_INTERFACE_INDEX] = *current_interface;
(*current_interface)++;
descriptor_buf[CDC_FIRST_INTERFACE_INDEX] = descriptor_counts->current_interface;
descriptor_buf[CDC_COMM_INTERFACE_INDEX] = descriptor_counts->current_interface;
descriptor_buf[CDC_UNION_MASTER_INTERFACE_INDEX] = descriptor_counts->current_interface;
descriptor_counts->current_interface++;
// Now store data interface number.
descriptor_buf[CDC_CALL_MANAGEMENT_DATA_INTERFACE_INDEX] = *current_interface;
descriptor_buf[CDC_UNION_SLAVE_INTERFACE_INDEX] = *current_interface;
descriptor_buf[CDC_DATA_INTERFACE_INDEX] = *current_interface;
(*current_interface)++;
descriptor_buf[CDC_CALL_MANAGEMENT_DATA_INTERFACE_INDEX] = descriptor_counts->current_interface;
descriptor_buf[CDC_UNION_SLAVE_INTERFACE_INDEX] = descriptor_counts->current_interface;
descriptor_buf[CDC_DATA_INTERFACE_INDEX] = descriptor_counts->current_interface;
descriptor_counts->current_interface++;
descriptor_buf[CDC_CONTROL_IN_ENDPOINT_INDEX] = 0x80 | (
console
? (USB_CDC_EP_NUM_NOTIFICATION ? USB_CDC_EP_NUM_NOTIFICATION : *current_endpoint)
: (USB_CDC2_EP_NUM_NOTIFICATION ? USB_CDC2_EP_NUM_NOTIFICATION : *current_endpoint));
(*current_endpoint)++;
descriptor_buf[CDC_DATA_OUT_ENDPOINT_INDEX] =
console
? (USB_CDC_EP_NUM_DATA_OUT ? USB_CDC_EP_NUM_DATA_OUT : *current_endpoint)
: (USB_CDC2_EP_NUM_DATA_OUT ? USB_CDC2_EP_NUM_DATA_OUT : *current_endpoint);
? (USB_CDC_EP_NUM_NOTIFICATION ? USB_CDC_EP_NUM_NOTIFICATION : descriptor_counts->current_endpoint)
: (USB_CDC2_EP_NUM_NOTIFICATION ? USB_CDC2_EP_NUM_NOTIFICATION : descriptor_counts->current_endpoint));
descriptor_counts->num_in_endpoints++;
descriptor_counts->current_endpoint++;
descriptor_buf[CDC_DATA_IN_ENDPOINT_INDEX] = 0x80 | (
console
? (USB_CDC_EP_NUM_DATA_IN ? USB_CDC_EP_NUM_DATA_IN : *current_endpoint)
: (USB_CDC2_EP_NUM_DATA_IN ? USB_CDC2_EP_NUM_DATA_IN : *current_endpoint));
(*current_endpoint)++;
? (USB_CDC_EP_NUM_DATA_IN ? USB_CDC_EP_NUM_DATA_IN : descriptor_counts->current_endpoint)
: (USB_CDC2_EP_NUM_DATA_IN ? USB_CDC2_EP_NUM_DATA_IN : descriptor_counts->current_endpoint));
descriptor_counts->num_in_endpoints++;
descriptor_buf[CDC_DATA_OUT_ENDPOINT_INDEX] =
console
? (USB_CDC_EP_NUM_DATA_OUT ? USB_CDC_EP_NUM_DATA_OUT : descriptor_counts->current_endpoint)
: (USB_CDC2_EP_NUM_DATA_OUT ? USB_CDC2_EP_NUM_DATA_OUT : descriptor_counts->current_endpoint);
descriptor_counts->num_out_endpoints++;
descriptor_counts->current_endpoint++;
usb_add_interface_string(*current_interface_string,
console ? console_cdc_comm_interface_name : data_cdc_comm_interface_name);

View File

@ -29,6 +29,7 @@
#include "py/mpconfig.h"
#include "py/objtuple.h"
#include "supervisor/usb.h"
bool usb_cdc_console_enabled(void);
bool usb_cdc_data_enabled(void);
@ -36,6 +37,6 @@ bool usb_cdc_data_enabled(void);
void usb_cdc_set_defaults(void);
size_t usb_cdc_descriptor_length(void);
size_t usb_cdc_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interface, uint8_t *current_endpoint, uint8_t *current_interface_string, bool repl);
size_t usb_cdc_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *descriptor_counts, uint8_t *current_interface_string, bool console);
#endif /* SHARED_MODULE_USB_CDC___INIT___H */

View File

@ -113,11 +113,11 @@ size_t usb_hid_descriptor_length(void) {
static const char usb_hid_interface_name[] = USB_INTERFACE_NAME " HID";
// This is the interface descriptor, not the report descriptor.
size_t usb_hid_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interface, uint8_t *current_endpoint, uint8_t *current_interface_string, uint16_t report_descriptor_length) {
size_t usb_hid_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *descriptor_counts, uint8_t *current_interface_string, uint16_t report_descriptor_length) {
memcpy(descriptor_buf, usb_hid_descriptor_template, sizeof(usb_hid_descriptor_template));
descriptor_buf[HID_DESCRIPTOR_INTERFACE_INDEX] = *current_interface;
(*current_interface)++;
descriptor_buf[HID_DESCRIPTOR_INTERFACE_INDEX] = descriptor_counts->current_interface;
descriptor_counts->current_interface++;
usb_add_interface_string(*current_interface_string, usb_hid_interface_name);
descriptor_buf[HID_DESCRIPTOR_INTERFACE_STRING_INDEX] = *current_interface_string;
@ -126,9 +126,13 @@ size_t usb_hid_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interfac
descriptor_buf[HID_DESCRIPTOR_LENGTH_INDEX] = report_descriptor_length & 0xFF;
descriptor_buf[HID_DESCRIPTOR_LENGTH_INDEX + 1] = (report_descriptor_length >> 8);
descriptor_buf[HID_IN_ENDPOINT_INDEX] = 0x80 | (USB_HID_EP_NUM_IN ? USB_HID_EP_NUM_IN : *current_endpoint);
descriptor_buf[HID_OUT_ENDPOINT_INDEX] = USB_HID_EP_NUM_OUT ? USB_HID_EP_NUM_OUT : *current_endpoint;
(*current_endpoint)++;
descriptor_buf[HID_IN_ENDPOINT_INDEX] =
0x80 | (USB_HID_EP_NUM_IN ? USB_HID_EP_NUM_IN : descriptor_counts->current_endpoint);
descriptor_counts->num_in_endpoints++;
descriptor_buf[HID_OUT_ENDPOINT_INDEX] =
USB_HID_EP_NUM_OUT ? USB_HID_EP_NUM_OUT : descriptor_counts->current_endpoint;
descriptor_counts->num_out_endpoints++;
descriptor_counts->current_endpoint++;
return sizeof(usb_hid_descriptor_template);
}

View File

@ -28,13 +28,14 @@
#define SHARED_MODULE_USB_HID___INIT___H
#include "shared-module/usb_hid/Device.h"
#include "supervisor/usb.h"
extern usb_hid_device_obj_t usb_hid_devices[];
bool usb_hid_enabled(void);
void usb_hid_set_defaults(void);
size_t usb_hid_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interface, uint8_t *current_endpoint, uint8_t *current_interface_string, uint16_t report_descriptor_length);
size_t usb_hid_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *descriptor_counts, uint8_t *current_interface_string, uint16_t report_descriptor_length);
size_t usb_hid_descriptor_length(void);
size_t usb_hid_report_descriptor_length(void);

View File

@ -175,36 +175,38 @@ static const char midi_audio_control_interface_name[] = USB_INTERFACE_NAME " Aud
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]";
size_t usb_midi_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interface, uint8_t *current_endpoint, uint8_t *current_interface_string) {
size_t usb_midi_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *descriptor_counts, uint8_t *current_interface_string) {
memcpy(descriptor_buf, usb_midi_descriptor_template, sizeof(usb_midi_descriptor_template));
descriptor_buf[MIDI_AUDIO_CONTROL_INTERFACE_NUMBER_INDEX] = *current_interface;
(*current_interface)++;
descriptor_buf[MIDI_AUDIO_CONTROL_INTERFACE_NUMBER_INDEX] = descriptor_counts->current_interface;
descriptor_counts->current_interface++;
descriptor_buf[MIDI_STREAMING_IN_ENDPOINT_INDEX] =
0x80 | (USB_MIDI_EP_NUM_IN ? USB_MIDI_EP_NUM_IN : *current_endpoint);
0x80 | (USB_MIDI_EP_NUM_IN ? USB_MIDI_EP_NUM_IN : descriptor_counts->current_endpoint);
descriptor_counts->num_in_endpoints++;
descriptor_buf[MIDI_STREAMING_OUT_ENDPOINT_INDEX] =
USB_MIDI_EP_NUM_OUT ? USB_MIDI_EP_NUM_OUT : *current_endpoint;
(*current_endpoint)++;
USB_MIDI_EP_NUM_OUT ? USB_MIDI_EP_NUM_OUT : descriptor_counts->current_endpoint;
descriptor_counts->num_out_endpoints++;
descriptor_counts->current_endpoint++;
descriptor_buf[MIDI_STREAMING_INTERFACE_NUMBER_INDEX] = *current_interface;
descriptor_buf[MIDI_STREAMING_INTERFACE_NUMBER_INDEX_2] = *current_interface;
(*current_interface)++;
descriptor_buf[MIDI_STREAMING_INTERFACE_NUMBER_INDEX] = descriptor_counts->current_interface;
descriptor_buf[MIDI_STREAMING_INTERFACE_NUMBER_INDEX_2] = descriptor_counts->current_interface;
descriptor_counts->current_interface++;
usb_add_interface_string(*current_interface_string, midi_streaming_interface_name);
descriptor_buf[MIDI_STREAMING_INTERFACE_STRING_INDEX] = *current_interface;
descriptor_buf[MIDI_STREAMING_INTERFACE_STRING_INDEX] = *current_interface_string;
(*current_interface_string)++;
usb_add_interface_string(*current_interface_string, midi_audio_control_interface_name);
descriptor_buf[MIDI_AUDIO_CONTROL_INTERFACE_STRING_INDEX] = *current_interface;
descriptor_buf[MIDI_AUDIO_CONTROL_INTERFACE_STRING_INDEX] = *current_interface_string;
(*current_interface_string)++;
usb_add_interface_string(*current_interface_string, midi_in_jack_name);
descriptor_buf[MIDI_IN_JACK_STRING_INDEX] = *current_interface;
descriptor_buf[MIDI_IN_JACK_STRING_INDEX] = *current_interface_string;
(*current_interface_string)++;
usb_add_interface_string(*current_interface_string, midi_out_jack_name);
descriptor_buf[MIDI_OUT_JACK_STRING_INDEX] = *current_interface;
descriptor_buf[MIDI_OUT_JACK_STRING_INDEX] = *current_interface_string;
(*current_interface_string)++;
return sizeof(usb_midi_descriptor_template);

View File

@ -27,11 +27,13 @@
#ifndef SHARED_MODULE_USB_MIDI___INIT___H
#define SHARED_MODULE_USB_MIDI___INIT___H
#include "supervisor/usb.h"
bool usb_midi_enabled(void);
void usb_midi_set_defaults(void);
void usb_midi_setup_ports(void);
size_t usb_midi_descriptor_length(void);
size_t usb_midi_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interface, uint8_t *current_endpoint, uint8_t *current_interface_string);
size_t usb_midi_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *descriptor_counts, uint8_t *current_interface_string);
#endif /* SHARED_MODULE_USB_MIDI___INIT___H */

View File

@ -184,9 +184,16 @@ static void usb_build_configuration_descriptor(void) {
configuration_descriptor[CONFIG_TOTAL_LENGTH_HI_INDEX] = (total_descriptor_length >> 8) & 0xFF;
// Number interfaces and endpoints.
// Endpoint 0 is already used for USB control, so start with 1.
uint8_t current_interface = 0;
uint8_t current_endpoint = 1;
// Endpoint 0 is already used for USB control,
// so start with 1 for the current endpoint and for the number of in and out endpoints
// already in use.
descriptor_counts_t descriptor_counts = {
.current_interface = 0,
.current_endpoint = 1,
.num_in_endpoints = 1,
.num_out_endpoints = 1,
};
uint8_t *descriptor_buf_remaining = configuration_descriptor + sizeof(configuration_descriptor_template);
@ -194,12 +201,13 @@ static void usb_build_configuration_descriptor(void) {
if (usb_cdc_console_enabled()) {
// Concatenate and fix up the CDC REPL descriptor.
descriptor_buf_remaining += usb_cdc_add_descriptor(
descriptor_buf_remaining, &current_interface, &current_endpoint, &current_interface_string, true);
descriptor_buf_remaining, &descriptor_counts, &current_interface_string, true /*console*/);
}
if (usb_cdc_data_enabled()) {
// Concatenate and fix up the CDC data descriptor.
descriptor_buf_remaining += usb_cdc_add_descriptor(
descriptor_buf_remaining, &current_interface, &current_endpoint, &current_interface_string, false);
descriptor_buf_remaining, &descriptor_counts, &current_interface_string, false /*console*/);
}
#endif
@ -207,14 +215,14 @@ static void usb_build_configuration_descriptor(void) {
if (storage_usb_enabled()) {
// Concatenate and fix up the MSC descriptor.
descriptor_buf_remaining += storage_usb_add_descriptor(
descriptor_buf_remaining, &current_interface, &current_endpoint, &current_interface_string);
descriptor_buf_remaining, &descriptor_counts, &current_interface_string);
}
#endif
#if CIRCUITPY_USB_HID
if (usb_hid_enabled()) {
descriptor_buf_remaining += usb_hid_add_descriptor(
descriptor_buf_remaining, &current_interface, &current_endpoint, &current_interface_string,
descriptor_buf_remaining, &descriptor_counts, &current_interface_string,
usb_hid_report_descriptor_length());
}
#endif
@ -223,18 +231,19 @@ static void usb_build_configuration_descriptor(void) {
if (usb_midi_enabled()) {
// Concatenate and fix up the MIDI descriptor.
descriptor_buf_remaining += usb_midi_add_descriptor(
descriptor_buf_remaining, &current_interface, &current_endpoint, &current_interface_string);
descriptor_buf_remaining, &descriptor_counts, &current_interface_string);
}
#endif
// Now we know how many interfaces have been used.
configuration_descriptor[CONFIG_NUM_INTERFACES_INDEX] = current_interface;
configuration_descriptor[CONFIG_NUM_INTERFACES_INDEX] = descriptor_counts.current_interface;
// Did we run out of endpoints?
if (current_endpoint > USB_NUM_EP) {
if (descriptor_counts.current_endpoint > USB_NUM_ENDPOINT_PAIRS ||
descriptor_counts.num_in_endpoints > USB_NUM_IN_ENDPOINTS ||
descriptor_counts.num_out_endpoints > USB_NUM_OUT_ENDPOINTS) {
reset_into_safe_mode(USB_TOO_MANY_ENDPOINTS);
}
}
// str must not be on the heap.

View File

@ -50,6 +50,14 @@ void init_usb_hardware(void);
// Temporary hook for code after init. Only used for RP2040.
void post_usb_init(void);
// Indexes and counts updated as descriptors are built.
typedef struct {
size_t current_interface;
size_t current_endpoint;
size_t num_in_endpoints;
size_t num_out_endpoints;
} descriptor_counts_t;
// Shared implementation.
bool usb_enabled(void);
void usb_add_interface_string(uint8_t interface_string_index, const char str[]);