Merge remote-tracking branch 'origin/main' into main

This commit is contained in:
Hosted Weblate 2021-05-14 20:25:08 +02:00
commit 0da2bbc6a4
41 changed files with 268 additions and 186 deletions

View File

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

View File

@ -710,13 +710,7 @@ msgid "CircuitPython core code crashed hard. Whoops!\n"
msgstr "" msgstr ""
#: supervisor/shared/safe_mode.c #: supervisor/shared/safe_mode.c
msgid "" msgid "CircuitPython was unable to allocate the heap."
"CircuitPython is in safe mode because you pressed the reset button during "
"boot. Press again to exit safe mode.\n"
msgstr ""
#: supervisor/shared/safe_mode.c
msgid "CircuitPython was unable to allocate the heap.\n"
msgstr "" msgstr ""
#: shared-module/bitbangio/SPI.c #: shared-module/bitbangio/SPI.c
@ -1638,10 +1632,6 @@ msgstr ""
msgid "Not playing" msgid "Not playing"
msgstr "" msgstr ""
#: main.c
msgid "Not running saved code.\n"
msgstr ""
#: shared-bindings/_bleio/__init__.c #: shared-bindings/_bleio/__init__.c
msgid "Not settable" msgid "Not settable"
msgstr "" msgstr ""
@ -1964,7 +1954,7 @@ msgid "Row entry must be digitalio.DigitalInOut"
msgstr "" msgstr ""
#: main.c #: main.c
msgid "Running in safe mode! " msgid "Running in safe mode! Not running saved code.\n"
msgstr "" msgstr ""
#: shared-module/sdcardio/SDCard.c #: shared-module/sdcardio/SDCard.c
@ -2089,13 +2079,13 @@ msgstr ""
#: supervisor/shared/safe_mode.c #: supervisor/shared/safe_mode.c
msgid "" msgid ""
"The CircuitPython heap was corrupted because the stack was too small.\n" "The CircuitPython heap was corrupted because the stack was too small.\n"
"Please increase the stack size if you know how, or if not:" "Increase the stack size if you know how. If not:"
msgstr "" msgstr ""
#: supervisor/shared/safe_mode.c #: supervisor/shared/safe_mode.c
msgid "" msgid ""
"The `microcontroller` module was used to boot into safe mode. Press reset to " "The `microcontroller` module was used to boot into safe mode. Press reset to "
"exit safe mode.\n" "exit safe mode."
msgstr "" msgstr ""
#: shared-bindings/rgbmatrix/RGBMatrix.c #: shared-bindings/rgbmatrix/RGBMatrix.c
@ -2106,7 +2096,7 @@ msgstr ""
msgid "" msgid ""
"The microcontroller's power dipped. Make sure your power supply provides\n" "The microcontroller's power dipped. Make sure your power supply provides\n"
"enough power for the whole circuit and press reset (after ejecting " "enough power for the whole circuit and press reset (after ejecting "
"CIRCUITPY).\n" "CIRCUITPY)."
msgstr "" msgstr ""
#: shared-module/audiomixer/MixerVoice.c #: shared-module/audiomixer/MixerVoice.c
@ -2404,7 +2394,12 @@ msgid "Writes not supported on Characteristic"
msgstr "" msgstr ""
#: supervisor/shared/safe_mode.c #: supervisor/shared/safe_mode.c
msgid "You are in safe mode: something unanticipated happened.\n" msgid "You are in safe mode because:\n"
msgstr ""
#: supervisor/shared/safe_mode.c
msgid ""
"You pressed the reset button during boot. Press again to exit safe mode."
msgstr "" msgstr ""
#: supervisor/shared/safe_mode.c #: supervisor/shared/safe_mode.c

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -743,8 +743,8 @@ msgstr ""
"de segurança.\n" "de segurança.\n"
#: supervisor/shared/safe_mode.c #: supervisor/shared/safe_mode.c
msgid "CircuitPython was unable to allocate the heap.\n" msgid "CircuitPython was unable to allocate the heap."
msgstr "O CircuitPython não conseguiu alocar o heap.\n" msgstr "O CircuitPython não conseguiu alocar o heap."
#: shared-module/bitbangio/SPI.c #: shared-module/bitbangio/SPI.c
msgid "Clock pin init failed." msgid "Clock pin init failed."
@ -4861,7 +4861,7 @@ msgstr "zi deve estar na forma (n_section, 2)"
#~ msgstr "Rodando em modo seguro! Atualização automática está desligada.\n" #~ msgstr "Rodando em modo seguro! Atualização automática está desligada.\n"
#~ msgid "Running in safe mode! Not running saved code.\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'" #~ msgid "__init__() should return None, not '%s'"
#~ msgstr "O __init__() deve retornar Nenhum, não '%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" "under start. Tryck igen för att lämna säkert läge.\n"
#: supervisor/shared/safe_mode.c #: supervisor/shared/safe_mode.c
msgid "CircuitPython was unable to allocate the heap.\n" msgid "CircuitPython was unable to allocate the heap."
msgstr "CircuitPython kunde inte allokera heap.\n" msgstr "CircuitPython kunde inte allokera heap."
#: shared-module/bitbangio/SPI.c #: shared-module/bitbangio/SPI.c
msgid "Clock pin init failed." 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" "chóng zhì ànniǔ. Zài àn yīcì tuìchū ānquán móshì.\n"
#: supervisor/shared/safe_mode.c #: supervisor/shared/safe_mode.c
msgid "CircuitPython was unable to allocate the heap.\n" msgid "CircuitPython was unable to allocate the heap."
msgstr "CircuitPython wúfǎ fēnpèi duī.\n" msgstr "CircuitPython wúfǎ fēnpèi duī."
#: shared-module/bitbangio/SPI.c #: shared-module/bitbangio/SPI.c
msgid "Clock pin init failed." msgid "Clock pin init failed."

22
main.c
View File

@ -261,18 +261,20 @@ STATIC void print_code_py_status_message(safe_mode_t safe_mode) {
serial_write_compressed(translate("Auto-reload is off.\n")); serial_write_compressed(translate("Auto-reload is off.\n"));
} }
if (safe_mode != NO_SAFE_MODE) { if (safe_mode != NO_SAFE_MODE) {
serial_write_compressed(translate("Running in safe mode! ")); serial_write_compressed(translate("Running in safe mode! Not running saved code.\n"));
serial_write_compressed(translate("Not running saved code.\n"));
} }
} }
STATIC bool run_code_py(safe_mode_t safe_mode) { STATIC bool run_code_py(safe_mode_t safe_mode) {
bool serial_connected_at_start = serial_connected(); bool serial_connected_at_start = serial_connected();
bool printed_safe_mode_message = false;
#if CIRCUITPY_AUTORELOAD_DELAY_MS > 0 #if CIRCUITPY_AUTORELOAD_DELAY_MS > 0
serial_write("\n"); if (serial_connected_at_start) {
print_code_py_status_message(safe_mode); serial_write("\r\n");
print_safe_mode_message(safe_mode); print_code_py_status_message(safe_mode);
serial_write("\n"); print_safe_mode_message(safe_mode);
printed_safe_mode_message = true;
}
#endif #endif
pyexec_result_t result; pyexec_result_t result;
@ -388,8 +390,11 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
print_code_py_status_message(safe_mode); print_code_py_status_message(safe_mode);
} }
print_safe_mode_message(safe_mode); if (!printed_safe_mode_message) {
serial_write("\n"); print_safe_mode_message(safe_mode);
printed_safe_mode_message = true;
}
serial_write("\r\n");
serial_write_compressed(translate("Press any key to enter the REPL. Use CTRL-D to reload.\n")); serial_write_compressed(translate("Press any key to enter the REPL. Use CTRL-D to reload.\n"));
printed_press_any_key = true; printed_press_any_key = true;
} }
@ -526,7 +531,6 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
usb_set_defaults(); usb_set_defaults();
#endif #endif
// TODO(tannewt): Re-add support for flashing boot error output.
if (ok_to_run) { if (ok_to_run) {
bool found_boot = maybe_run_list(boot_py_filenames, NULL); bool found_boot = maybe_run_list(boot_py_filenames, NULL);
(void) found_boot; (void) found_boot;

View File

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

View File

@ -1,7 +1,7 @@
USB_HIGHSPEED = 1 USB_HIGHSPEED = 1
# Number of USB endpoint pairs. # 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 # 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. # $(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_NVM = 1
CIRCUITPY_PS2IO ?= 1 CIRCUITPY_PS2IO ?= 1
CIRCUITPY_TOUCHIO_USE_NATIVE ?= 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_WIFI = 1
CIRCUITPY_WATCHDOG ?= 1 CIRCUITPY_WATCHDOG ?= 1
@ -39,4 +34,14 @@ CIRCUITPY_ESPIDF = 1
CIRCUITPY_MODULE ?= none 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 INTERNAL_LIBM = 1
# Number of USB endpoint pairs. # Number of USB endpoint pairs.
USB_NUM_EP = 16 USB_NUM_ENDPOINT_PAIRS = 16
# Longints can be implemented as mpz, as longlong, or not # Longints can be implemented as mpz, as longlong, or not
LONGINT_IMPL = MPZ LONGINT_IMPL = MPZ

View File

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

View File

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

View File

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

View File

@ -22,6 +22,8 @@ CIRCUITPY_AUDIOPWMIO = 0
CIRCUITPY_BUSDEVICE = 0 CIRCUITPY_BUSDEVICE = 0
CIRCUITPY_BITMAPTOOLS = 0 CIRCUITPY_BITMAPTOOLS = 0
CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_FRAMEBUFFERIO = 0
CIRCUITPY_MIDI = 0
CIRCUITPY_MSGPACK = 0
CIRCUITPY_ULAB = 0 CIRCUITPY_ULAB = 0
CIRCUITPY_VECTORIO = 0 CIRCUITPY_VECTORIO = 0

View File

@ -16,3 +16,5 @@ LD_FILE = boards/STM32F411_fs.ld
# Too big for the flash # Too big for the flash
CIRCUITPY_AUDIOCORE = 0 CIRCUITPY_AUDIOCORE = 0
CIRCUITPY_AUDIOPWMIO = 0 CIRCUITPY_AUDIOPWMIO = 0
CIRCUITPY_MIDI = 0
CIRCUITPY_MSGPACK = 0

View File

@ -15,3 +15,5 @@ LD_FILE = boards/STM32F411_fs.ld
# Too big for the flash # Too big for the flash
CIRCUITPY_AUDIOCORE = 0 CIRCUITPY_AUDIOCORE = 0
CIRCUITPY_AUDIOPWMIO = 0 CIRCUITPY_AUDIOPWMIO = 0
CIRCUITPY_MIDI = 0
CIRCUITPY_MSGPACK = 0

View File

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

View File

@ -338,8 +338,18 @@ CFLAGS += -DCIRCUITPY_UHEAP=$(CIRCUITPY_UHEAP)
CIRCUITPY_USB ?= 1 CIRCUITPY_USB ?= 1
CFLAGS += -DCIRCUITPY_USB=$(CIRCUITPY_USB) CFLAGS += -DCIRCUITPY_USB=$(CIRCUITPY_USB)
# Compute this value once, so the shell command is not reinvoked many times. # Compute these value once, so the shell command is not reinvoked many times.
USB_NUM_EP_8_OR_GREATER := $(shell expr $(USB_NUM_EP) '>=' 8) 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 CIRCUITPY_USB_CDC ?= 1
CFLAGS += -DCIRCUITPY_USB_CDC=$(CIRCUITPY_USB_CDC) CFLAGS += -DCIRCUITPY_USB_CDC=$(CIRCUITPY_USB_CDC)
@ -348,20 +358,21 @@ CFLAGS += -DCIRCUITPY_USB_CDC_CONSOLE_ENABLED_DEFAULT=$(CIRCUITPY_USB_CDC_CONSOL
CIRCUITPY_USB_CDC_DATA_ENABLED_DEFAULT ?= 0 CIRCUITPY_USB_CDC_DATA_ENABLED_DEFAULT ?= 0
CFLAGS += -DCIRCUITPY_USB_CDC_DATA_ENABLED_DEFAULT=$(CIRCUITPY_USB_CDC_DATA_ENABLED_DEFAULT) 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 CIRCUITPY_USB_HID ?= 1
CFLAGS += -DCIRCUITPY_USB_HID=$(CIRCUITPY_USB_HID) 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) CFLAGS += -DCIRCUITPY_USB_HID_ENABLED_DEFAULT=$(CIRCUITPY_USB_HID_ENABLED_DEFAULT)
# MIDI is usually available if there are at least 8 endpoints. # MIDI is available by default, but is not turned on if there are fewer than 8 endpoints.
CIRCUITPY_USB_MIDI ?= $(USB_NUM_EP_8_OR_GREATER) CIRCUITPY_USB_MIDI ?= 1
CFLAGS += -DCIRCUITPY_USB_MIDI=$(CIRCUITPY_USB_MIDI) 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) CFLAGS += -DCIRCUITPY_USB_MIDI_ENABLED_DEFAULT=$(CIRCUITPY_USB_MIDI_ENABLED_DEFAULT)
CIRCUITPY_USB_MSC ?= 1 CIRCUITPY_USB_MSC ?= 1
CFLAGS += -DCIRCUITPY_USB_MSC=$(CIRCUITPY_USB_MSC) CFLAGS += -DCIRCUITPY_USB_MSC=$(CIRCUITPY_USB_MSC)
CIRCUITPY_USB_MSC_ENABLED_DEFAULT = $(CIRCUITPY_USB_MSC) CIRCUITPY_USB_MSC_ENABLED_DEFAULT ?= $(CIRCUITPY_USB_MSC)
CFLAGS += -DCIRCUITPY_USB_MSC_ENABLED_DEFAULT=$(CIRCUITPY_USB_MSC_ENABLED_DEFAULT) CFLAGS += -DCIRCUITPY_USB_MSC_ENABLED_DEFAULT=$(CIRCUITPY_USB_MSC_ENABLED_DEFAULT)
# Defaulting this to OFF initially because it has only been tested on a # Defaulting this to OFF initially because it has only been tested on a
@ -370,10 +381,10 @@ CFLAGS += -DCIRCUITPY_USB_MSC_ENABLED_DEFAULT=$(CIRCUITPY_USB_MSC_ENABLED_DEFAUL
CIRCUITPY_USB_VENDOR ?= 0 CIRCUITPY_USB_VENDOR ?= 0
CFLAGS += -DCIRCUITPY_USB_VENDOR=$(CIRCUITPY_USB_VENDOR) CFLAGS += -DCIRCUITPY_USB_VENDOR=$(CIRCUITPY_USB_VENDOR)
ifndef USB_NUM_EP ifndef USB_NUM_ENDPOINT_PAIRS
$(error "USB_NUM_EP (number of USB endpoint pairs)must be defined") $(error "USB_NUM_ENDPOINT_PAIRS (number of USB endpoint pairs)must be defined")
endif endif
CFLAGS += -DUSB_NUM_EP=$(USB_NUM_EP) CFLAGS += -DUSB_NUM_ENDPOINT_PAIRS=$(USB_NUM_ENDPOINT_PAIRS)
# For debugging. # For debugging.
CIRCUITPY_USTACK ?= 0 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. //| """Enabled presenting ``CIRCUITPY`` as a USB mass storage device.
//| By default, the device is enabled and ``CIRCUITPY`` is visible, //| By default, the device is enabled and ``CIRCUITPY`` is visible,
//| so you do not normally need to call this function. //| 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) { 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. //| :param console bool: Enable or disable the `console` USB serial device.
//| True to enable; False to disable. Enabled by default. //| True to enable; False to disable. Enabled by default.
//| :param data bool: Enable or disable the `data` USB serial device. //| :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) { 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, ...] //| 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: //| def disable() -> None:
//| """Do not present any USB HID devices to the host computer. //| """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) { STATIC mp_obj_t usb_hid_disable(void) {
if (!common_hal_usb_hid_disable()) { if (!common_hal_usb_hid_disable()) {
mp_raise_RuntimeError(translate("Cannot change USB devices now")); 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`` //| 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 //| 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. //| 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: //| def disable() -> None:
//| """Disable presenting a USB MIDI device to the host. //| """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.""" //| 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: //| def enable() -> None:
//| """Enable presenting a USB MIDI device to the host. //| """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. //| 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) { 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"; 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)); memcpy(descriptor_buf, usb_msc_descriptor_template, sizeof(usb_msc_descriptor_template));
descriptor_buf[MSC_INTERFACE_INDEX] = *current_interface; descriptor_buf[MSC_INTERFACE_INDEX] = descriptor_counts->current_interface;
(*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_IN_ENDPOINT_INDEX] =
descriptor_buf[MSC_OUT_ENDPOINT_INDEX] = USB_MSC_EP_NUM_OUT ? USB_MSC_EP_NUM_OUT : *current_endpoint; 0x80 | (USB_MSC_EP_NUM_IN ? USB_MSC_EP_NUM_IN : descriptor_counts->current_endpoint);
(*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); usb_add_interface_string(*current_interface_string, storage_interface_name);
descriptor_buf[MSC_INTERFACE_STRING_INDEX] = *current_interface_string; descriptor_buf[MSC_INTERFACE_STRING_INDEX] = *current_interface_string;

View File

@ -28,12 +28,13 @@
#define SHARED_MODULE_STORAGE___INIT___H #define SHARED_MODULE_STORAGE___INIT___H
#include "py/mpconfig.h" #include "py/mpconfig.h"
#include "supervisor/usb.h"
#if CIRCUITPY_USB #if CIRCUITPY_USB
bool storage_usb_enabled(void); bool storage_usb_enabled(void);
void storage_usb_set_defaults(void); void storage_usb_set_defaults(void);
size_t storage_usb_descriptor_length(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
#endif // SHARED_MODULE_STORAGE___INIT___H #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); 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)); memcpy(descriptor_buf, usb_cdc_descriptor_template, sizeof(usb_cdc_descriptor_template));
// Store comm interface number. // Store comm interface number.
descriptor_buf[CDC_FIRST_INTERFACE_INDEX] = *current_interface; descriptor_buf[CDC_FIRST_INTERFACE_INDEX] = descriptor_counts->current_interface;
descriptor_buf[CDC_COMM_INTERFACE_INDEX] = *current_interface; descriptor_buf[CDC_COMM_INTERFACE_INDEX] = descriptor_counts->current_interface;
descriptor_buf[CDC_UNION_MASTER_INTERFACE_INDEX] = *current_interface; descriptor_buf[CDC_UNION_MASTER_INTERFACE_INDEX] = descriptor_counts->current_interface;
(*current_interface)++; descriptor_counts->current_interface++;
// Now store data interface number. // Now store data interface number.
descriptor_buf[CDC_CALL_MANAGEMENT_DATA_INTERFACE_INDEX] = *current_interface; descriptor_buf[CDC_CALL_MANAGEMENT_DATA_INTERFACE_INDEX] = descriptor_counts->current_interface;
descriptor_buf[CDC_UNION_SLAVE_INTERFACE_INDEX] = *current_interface; descriptor_buf[CDC_UNION_SLAVE_INTERFACE_INDEX] = descriptor_counts->current_interface;
descriptor_buf[CDC_DATA_INTERFACE_INDEX] = *current_interface; descriptor_buf[CDC_DATA_INTERFACE_INDEX] = descriptor_counts->current_interface;
(*current_interface)++; descriptor_counts->current_interface++;
descriptor_buf[CDC_CONTROL_IN_ENDPOINT_INDEX] = 0x80 | ( descriptor_buf[CDC_CONTROL_IN_ENDPOINT_INDEX] = 0x80 | (
console console
? (USB_CDC_EP_NUM_NOTIFICATION ? USB_CDC_EP_NUM_NOTIFICATION : *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 : *current_endpoint)); : (USB_CDC2_EP_NUM_NOTIFICATION ? USB_CDC2_EP_NUM_NOTIFICATION : descriptor_counts->current_endpoint));
(*current_endpoint)++; descriptor_counts->num_in_endpoints++;
descriptor_counts->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);
descriptor_buf[CDC_DATA_IN_ENDPOINT_INDEX] = 0x80 | ( descriptor_buf[CDC_DATA_IN_ENDPOINT_INDEX] = 0x80 | (
console console
? (USB_CDC_EP_NUM_DATA_IN ? USB_CDC_EP_NUM_DATA_IN : *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 : *current_endpoint)); : (USB_CDC2_EP_NUM_DATA_IN ? USB_CDC2_EP_NUM_DATA_IN : descriptor_counts->current_endpoint));
(*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, usb_add_interface_string(*current_interface_string,
console ? console_cdc_comm_interface_name : data_cdc_comm_interface_name); console ? console_cdc_comm_interface_name : data_cdc_comm_interface_name);

View File

@ -29,6 +29,7 @@
#include "py/mpconfig.h" #include "py/mpconfig.h"
#include "py/objtuple.h" #include "py/objtuple.h"
#include "supervisor/usb.h"
bool usb_cdc_console_enabled(void); bool usb_cdc_console_enabled(void);
bool usb_cdc_data_enabled(void); bool usb_cdc_data_enabled(void);
@ -36,6 +37,6 @@ bool usb_cdc_data_enabled(void);
void usb_cdc_set_defaults(void); void usb_cdc_set_defaults(void);
size_t usb_cdc_descriptor_length(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 */ #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"; static const char usb_hid_interface_name[] = USB_INTERFACE_NAME " HID";
// This is the interface descriptor, not the report descriptor. // 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)); memcpy(descriptor_buf, usb_hid_descriptor_template, sizeof(usb_hid_descriptor_template));
descriptor_buf[HID_DESCRIPTOR_INTERFACE_INDEX] = *current_interface; descriptor_buf[HID_DESCRIPTOR_INTERFACE_INDEX] = descriptor_counts->current_interface;
(*current_interface)++; descriptor_counts->current_interface++;
usb_add_interface_string(*current_interface_string, usb_hid_interface_name); usb_add_interface_string(*current_interface_string, usb_hid_interface_name);
descriptor_buf[HID_DESCRIPTOR_INTERFACE_STRING_INDEX] = *current_interface_string; 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] = report_descriptor_length & 0xFF;
descriptor_buf[HID_DESCRIPTOR_LENGTH_INDEX + 1] = (report_descriptor_length >> 8); 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_IN_ENDPOINT_INDEX] =
descriptor_buf[HID_OUT_ENDPOINT_INDEX] = USB_HID_EP_NUM_OUT ? USB_HID_EP_NUM_OUT : *current_endpoint; 0x80 | (USB_HID_EP_NUM_IN ? USB_HID_EP_NUM_IN : descriptor_counts->current_endpoint);
(*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); return sizeof(usb_hid_descriptor_template);
} }

View File

@ -28,13 +28,14 @@
#define SHARED_MODULE_USB_HID___INIT___H #define SHARED_MODULE_USB_HID___INIT___H
#include "shared-module/usb_hid/Device.h" #include "shared-module/usb_hid/Device.h"
#include "supervisor/usb.h"
extern usb_hid_device_obj_t usb_hid_devices[]; extern usb_hid_device_obj_t usb_hid_devices[];
bool usb_hid_enabled(void); bool usb_hid_enabled(void);
void usb_hid_set_defaults(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_descriptor_length(void);
size_t usb_hid_report_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_in_jack_name[] = USB_INTERFACE_NAME " usb_midi.ports[0]";
static const char midi_out_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)); memcpy(descriptor_buf, usb_midi_descriptor_template, sizeof(usb_midi_descriptor_template));
descriptor_buf[MIDI_AUDIO_CONTROL_INTERFACE_NUMBER_INDEX] = *current_interface; descriptor_buf[MIDI_AUDIO_CONTROL_INTERFACE_NUMBER_INDEX] = descriptor_counts->current_interface;
(*current_interface)++; descriptor_counts->current_interface++;
descriptor_buf[MIDI_STREAMING_IN_ENDPOINT_INDEX] = 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] = descriptor_buf[MIDI_STREAMING_OUT_ENDPOINT_INDEX] =
USB_MIDI_EP_NUM_OUT ? USB_MIDI_EP_NUM_OUT : *current_endpoint; USB_MIDI_EP_NUM_OUT ? USB_MIDI_EP_NUM_OUT : descriptor_counts->current_endpoint;
(*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] = descriptor_counts->current_interface;
descriptor_buf[MIDI_STREAMING_INTERFACE_NUMBER_INDEX_2] = *current_interface; descriptor_buf[MIDI_STREAMING_INTERFACE_NUMBER_INDEX_2] = descriptor_counts->current_interface;
(*current_interface)++; descriptor_counts->current_interface++;
usb_add_interface_string(*current_interface_string, midi_streaming_interface_name); 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)++; (*current_interface_string)++;
usb_add_interface_string(*current_interface_string, 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; descriptor_buf[MIDI_AUDIO_CONTROL_INTERFACE_STRING_INDEX] = *current_interface_string;
(*current_interface_string)++; (*current_interface_string)++;
usb_add_interface_string(*current_interface_string, midi_in_jack_name); 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)++; (*current_interface_string)++;
usb_add_interface_string(*current_interface_string, midi_out_jack_name); 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)++; (*current_interface_string)++;
return sizeof(usb_midi_descriptor_template); return sizeof(usb_midi_descriptor_template);

View File

@ -27,11 +27,13 @@
#ifndef SHARED_MODULE_USB_MIDI___INIT___H #ifndef SHARED_MODULE_USB_MIDI___INIT___H
#define SHARED_MODULE_USB_MIDI___INIT___H #define SHARED_MODULE_USB_MIDI___INIT___H
#include "supervisor/usb.h"
bool usb_midi_enabled(void); bool usb_midi_enabled(void);
void usb_midi_set_defaults(void); void usb_midi_set_defaults(void);
void usb_midi_setup_ports(void); void usb_midi_setup_ports(void);
size_t usb_midi_descriptor_length(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 */ #endif /* SHARED_MODULE_USB_MIDI___INIT___H */

View File

@ -117,13 +117,17 @@ void __attribute__((noinline,)) reset_into_safe_mode(safe_mode_t reason) {
#define FILE_AN_ISSUE translate("\nPlease file an issue with the contents of your CIRCUITPY drive at \nhttps://github.com/adafruit/circuitpython/issues\n")
void print_safe_mode_message(safe_mode_t reason) { void print_safe_mode_message(safe_mode_t reason) {
if (reason == NO_SAFE_MODE) { if (reason == NO_SAFE_MODE) {
return; return;
} }
serial_write("\n");
serial_write("\r\n");
serial_write_compressed(translate("You are in safe mode because:\n"));
const compressed_string_t *message = NULL;
// First check for safe mode reasons that do not necessarily reflect bugs.
switch (reason) { switch (reason) {
case USER_SAFE_MODE: case USER_SAFE_MODE:
@ -133,40 +137,40 @@ void print_safe_mode_message(safe_mode_t reason) {
serial_write_compressed(BOARD_USER_SAFE_MODE_ACTION); serial_write_compressed(BOARD_USER_SAFE_MODE_ACTION);
serial_write_compressed(translate("To exit, please reset the board without ")); serial_write_compressed(translate("To exit, please reset the board without "));
serial_write_compressed(BOARD_USER_SAFE_MODE_ACTION); serial_write_compressed(BOARD_USER_SAFE_MODE_ACTION);
#else
break;
#endif #endif
return; break;
case MANUAL_SAFE_MODE: case MANUAL_SAFE_MODE:
serial_write_compressed(translate("CircuitPython is in safe mode because you pressed the reset button during boot. Press again to exit safe mode.\n")); message = translate("You pressed the reset button during boot. Press again to exit safe mode.");
return; break;
case PROGRAMMATIC_SAFE_MODE: case PROGRAMMATIC_SAFE_MODE:
serial_write_compressed(translate("The `microcontroller` module was used to boot into safe mode. Press reset to exit safe mode.\n")); message = translate("The `microcontroller` module was used to boot into safe mode. Press reset to exit safe mode.");
return; break;
case BROWNOUT:
message = translate("The microcontroller's power dipped. Make sure your power supply provides\nenough power for the whole circuit and press reset (after ejecting CIRCUITPY).");
break;
case USB_TOO_MANY_ENDPOINTS:
message = translate("USB devices need more endpoints than are available.");
break;
case USB_TOO_MANY_INTERFACE_NAMES:
message = translate("USB devices specify too many interface names.");
break;
case WATCHDOG_RESET:
message = translate("Watchdog timer expired.");
break;
default: default:
break; break;
} }
serial_write_compressed(translate("You are in safe mode: something unanticipated happened.\n")); if (message) {
switch (reason) { serial_write_compressed(message);
case BROWNOUT: serial_write("\r\n");
serial_write_compressed(translate("The microcontroller's power dipped. Make sure your power supply provides\nenough power for the whole circuit and press reset (after ejecting CIRCUITPY).\n")); return;
return;
case HEAP_OVERWRITTEN:
serial_write_compressed(translate("The CircuitPython heap was corrupted because the stack was too small.\nPlease increase the stack size if you know how, or if not:"));
serial_write_compressed(FILE_AN_ISSUE);
return;
case NO_HEAP:
serial_write_compressed(translate("CircuitPython was unable to allocate the heap.\n"));
serial_write_compressed(FILE_AN_ISSUE);
return;
default:
break;
} }
// Something worse happened.
serial_write_compressed(translate("CircuitPython core code crashed hard. Whoops!\n")); serial_write_compressed(translate("CircuitPython core code crashed hard. Whoops!\n"));
const compressed_string_t *message = NULL;
switch (reason) { switch (reason) {
case HARD_CRASH: case HARD_CRASH:
message = translate("Crash into the HardFault_Handler."); message = translate("Crash into the HardFault_Handler.");
@ -177,6 +181,12 @@ void print_safe_mode_message(safe_mode_t reason) {
case MICROPY_FATAL_ERROR: case MICROPY_FATAL_ERROR:
message = translate("Fatal error."); message = translate("Fatal error.");
break; break;
case NO_HEAP:
message = translate("CircuitPython was unable to allocate the heap.");
break;
case HEAP_OVERWRITTEN:
message = translate("The CircuitPython heap was corrupted because the stack was too small.\nIncrease the stack size if you know how. If not:");
break;
case GC_ALLOC_OUTSIDE_VM: case GC_ALLOC_OUTSIDE_VM:
message = translate("Attempted heap allocation when VM not running."); message = translate("Attempted heap allocation when VM not running.");
break; break;
@ -193,19 +203,10 @@ void print_safe_mode_message(safe_mode_t reason) {
case MEM_MANAGE: case MEM_MANAGE:
message = translate("Invalid memory access."); message = translate("Invalid memory access.");
break; break;
case WATCHDOG_RESET:
message = translate("Watchdog timer expired.");
break;
case USB_TOO_MANY_ENDPOINTS:
message = translate("USB devices need more endpoints than are available.");
break;
case USB_TOO_MANY_INTERFACE_NAMES:
message = translate("USB devices specify too many interface names.");
break;
default: default:
message = translate("Unknown reason."); message = translate("Unknown reason.");
break; break;
} }
serial_write_compressed(message); serial_write_compressed(message);
serial_write_compressed(FILE_AN_ISSUE); serial_write_compressed(translate("\nPlease file an issue with the contents of your CIRCUITPY drive at \nhttps://github.com/adafruit/circuitpython/issues\n"));
} }

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; configuration_descriptor[CONFIG_TOTAL_LENGTH_HI_INDEX] = (total_descriptor_length >> 8) & 0xFF;
// Number interfaces and endpoints. // Number interfaces and endpoints.
// Endpoint 0 is already used for USB control, so start with 1. // Endpoint 0 is already used for USB control,
uint8_t current_interface = 0; // so start with 1 for the current endpoint and for the number of in and out endpoints
uint8_t current_endpoint = 1; // 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); 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()) { if (usb_cdc_console_enabled()) {
// Concatenate and fix up the CDC REPL descriptor. // Concatenate and fix up the CDC REPL descriptor.
descriptor_buf_remaining += usb_cdc_add_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()) { if (usb_cdc_data_enabled()) {
// Concatenate and fix up the CDC data descriptor. // Concatenate and fix up the CDC data descriptor.
descriptor_buf_remaining += usb_cdc_add_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 #endif
@ -207,14 +215,14 @@ static void usb_build_configuration_descriptor(void) {
if (storage_usb_enabled()) { if (storage_usb_enabled()) {
// Concatenate and fix up the MSC descriptor. // Concatenate and fix up the MSC descriptor.
descriptor_buf_remaining += storage_usb_add_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 #endif
#if CIRCUITPY_USB_HID #if CIRCUITPY_USB_HID
if (usb_hid_enabled()) { if (usb_hid_enabled()) {
descriptor_buf_remaining += usb_hid_add_descriptor( 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()); usb_hid_report_descriptor_length());
} }
#endif #endif
@ -223,18 +231,19 @@ static void usb_build_configuration_descriptor(void) {
if (usb_midi_enabled()) { if (usb_midi_enabled()) {
// Concatenate and fix up the MIDI descriptor. // Concatenate and fix up the MIDI descriptor.
descriptor_buf_remaining += usb_midi_add_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 #endif
// Now we know how many interfaces have been used. // 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? // Did we run out of endpoints?
if (current_endpoint - 1 > 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); reset_into_safe_mode(USB_TOO_MANY_ENDPOINTS);
} }
} }
// str must not be on the heap. // 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. // Temporary hook for code after init. Only used for RP2040.
void post_usb_init(void); 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. // Shared implementation.
bool usb_enabled(void); bool usb_enabled(void);
void usb_add_interface_string(uint8_t interface_string_index, const char str[]); void usb_add_interface_string(uint8_t interface_string_index, const char str[]);