summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/atmel-samd/mpconfigport.mk22
-rw-r--r--ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.mk1
-rw-r--r--ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.mk1
-rw-r--r--ports/esp32s2/boards/unexpectedmaker_feathers2/mpconfigboard.mk1
-rw-r--r--ports/esp32s2/boards/unexpectedmaker_feathers2_prerelease/mpconfigboard.mk1
-rw-r--r--ports/litex/mpconfigport.mk3
-rw-r--r--ports/mimxrt10xx/mpconfigport.mk3
-rw-r--r--ports/nrf/mpconfigport.mk3
-rw-r--r--ports/raspberrypi/mpconfigport.mk1
-rw-r--r--ports/stm/boards/thunderpack_v12/mpconfigboard.mk4
-rw-r--r--ports/stm/mpconfigport.mk7
-rw-r--r--py/circuitpy_mpconfig.mk99
-rw-r--r--supervisor/shared/usb/tusb_config.h7
-rw-r--r--supervisor/supervisor.mk112
-rw-r--r--tools/gen_usb_descriptor.py912
m---------tools/usb_descriptor0
16 files changed, 740 insertions, 437 deletions
diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk
index fb9cdf2e6..9839a2aa4 100644
--- a/ports/atmel-samd/mpconfigport.mk
+++ b/ports/atmel-samd/mpconfigport.mk
@@ -18,7 +18,16 @@ ifeq ($(LONGINT_IMPL),LONGLONG)
MPY_TOOL_LONGINT_IMPL = -mlongint-impl=longlong
endif
+INTERNAL_LIBM = 1
+
+USB_SERIAL_NUMBER_LENGTH = 32
+
+# Number of USB endpoint pairs.
+USB_NUM_EP = 8
+
+######################################################################
# Put samd21-only choices here.
+
ifeq ($(CHIP_FAMILY),samd21)
# The ?='s allow overriding in mpconfigboard.mk.
@@ -40,7 +49,9 @@ CIRCUITPY_SDCARDIO ?= 0
CIRCUITPY_FRAMEBUFFERIO ?= 0
# SAMD21 needs separate endpoint pairs for MSC BULK IN and BULK OUT, otherwise it's erratic.
+# Because of that, there aren't enough endpoints for serial2.
USB_MSC_EP_NUM_OUT = 1
+CIRCUITPY_USB_SERIAL2 = 0
CIRCUITPY_ULAB = 0
@@ -55,9 +66,13 @@ CIRCUITPY_TERMINALIO = 0
endif
endif # samd21
+######################################################################
+######################################################################
# Put samd51-only choices here.
+
ifeq ($(CHIP_FAMILY),samd51)
+
# No native touchio on SAMD51.
CIRCUITPY_TOUCHIO_USE_NATIVE = 0
@@ -70,9 +85,4 @@ CIRCUITPY_RGBMATRIX ?= $(CIRCUITPY_FULL_BUILD)
CIRCUITPY_FRAMEBUFFERIO ?= $(CIRCUITPY_FULL_BUILD)
endif # samd51
-
-INTERNAL_LIBM = 1
-
-USB_SERIAL_NUMBER_LENGTH = 32
-
-USB_NUM_EP = 8
+######################################################################
diff --git a/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.mk b/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.mk
index 38a7ed1fb..79b45fd92 100644
--- a/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.mk
+++ b/ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.mk
@@ -2,7 +2,6 @@ USB_VID = 0x303a
USB_PID = 0x8007
USB_PRODUCT = "TTGO T8 ESP32-S2"
USB_MANUFACTURER = "LILYGO"
-USB_DEVICES = "CDC,MSC,HID"
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = MPZ
diff --git a/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.mk b/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.mk
index 515617095..783e7ad4c 100644
--- a/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.mk
+++ b/ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.mk
@@ -2,7 +2,6 @@ USB_VID = 0x239A
USB_PID = 0x80C6
USB_PRODUCT = "microS2"
USB_MANUFACTURER = "microDev"
-USB_DEVICES = "CDC,MSC,HID"
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = MPZ
diff --git a/ports/esp32s2/boards/unexpectedmaker_feathers2/mpconfigboard.mk b/ports/esp32s2/boards/unexpectedmaker_feathers2/mpconfigboard.mk
index 9857c0761..d045cc214 100644
--- a/ports/esp32s2/boards/unexpectedmaker_feathers2/mpconfigboard.mk
+++ b/ports/esp32s2/boards/unexpectedmaker_feathers2/mpconfigboard.mk
@@ -2,7 +2,6 @@ USB_VID = 0x239A
USB_PID = 0x80AC
USB_PRODUCT = "FeatherS2"
USB_MANUFACTURER = "UnexpectedMaker"
-USB_DEVICES = "CDC,MSC,HID"
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = MPZ
diff --git a/ports/esp32s2/boards/unexpectedmaker_feathers2_prerelease/mpconfigboard.mk b/ports/esp32s2/boards/unexpectedmaker_feathers2_prerelease/mpconfigboard.mk
index 9857c0761..d045cc214 100644
--- a/ports/esp32s2/boards/unexpectedmaker_feathers2_prerelease/mpconfigboard.mk
+++ b/ports/esp32s2/boards/unexpectedmaker_feathers2_prerelease/mpconfigboard.mk
@@ -2,7 +2,6 @@ USB_VID = 0x239A
USB_PID = 0x80AC
USB_PRODUCT = "FeatherS2"
USB_MANUFACTURER = "UnexpectedMaker"
-USB_DEVICES = "CDC,MSC,HID"
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = MPZ
diff --git a/ports/litex/mpconfigport.mk b/ports/litex/mpconfigport.mk
index 003fb5c2c..af6a94e64 100644
--- a/ports/litex/mpconfigport.mk
+++ b/ports/litex/mpconfigport.mk
@@ -6,6 +6,9 @@ MPY_TOOL_LONGINT_IMPL = -mlongint-impl=mpz
# Internal math library is substantially smaller than toolchain one
INTERNAL_LIBM = 1
+# Number of USB endpoint pairs.
+USB_NUM_EP = 16
+
# Chip supplied serial number, in bytes
USB_SERIAL_NUMBER_LENGTH = 30
diff --git a/ports/mimxrt10xx/mpconfigport.mk b/ports/mimxrt10xx/mpconfigport.mk
index b4cc9586a..de594b14b 100644
--- a/ports/mimxrt10xx/mpconfigport.mk
+++ b/ports/mimxrt10xx/mpconfigport.mk
@@ -17,6 +17,9 @@ INTERNAL_LIBM = 1
USB_SERIAL_NUMBER_LENGTH = 32
USB_HIGHSPEED = 1
+# Number of USB endpoint pairs.
+USB_NUM_EP = 8
+
INTERNAL_FLASH_FILESYSTEM = 1
CIRCUITPY_AUDIOIO = 0
diff --git a/ports/nrf/mpconfigport.mk b/ports/nrf/mpconfigport.mk
index 9560064fb..83924ff79 100644
--- a/ports/nrf/mpconfigport.mk
+++ b/ports/nrf/mpconfigport.mk
@@ -11,6 +11,9 @@ INTERNAL_LIBM = 1
USB_SERIAL_NUMBER_LENGTH = 16
+# Number of USB endpoint pairs.
+USB_NUM_EP = 8
+
# All nRF ports have longints.
LONGINT_IMPL = MPZ
diff --git a/ports/raspberrypi/mpconfigport.mk b/ports/raspberrypi/mpconfigport.mk
index d0a21a7b4..6fb4ffaae 100644
--- a/ports/raspberrypi/mpconfigport.mk
+++ b/ports/raspberrypi/mpconfigport.mk
@@ -44,4 +44,5 @@ INTERNAL_LIBM = 1
USB_SERIAL_NUMBER_LENGTH = 32
+# Number of USB endpoint pairs.
USB_NUM_EP = 8
diff --git a/ports/stm/boards/thunderpack_v12/mpconfigboard.mk b/ports/stm/boards/thunderpack_v12/mpconfigboard.mk
index a2e1da101..4436f04b7 100644
--- a/ports/stm/boards/thunderpack_v12/mpconfigboard.mk
+++ b/ports/stm/boards/thunderpack_v12/mpconfigboard.mk
@@ -2,7 +2,9 @@ USB_VID = 0x239A
USB_PID = 0x8071
USB_PRODUCT = "Thunderpack STM32F411"
USB_MANUFACTURER = "Jeremy Gillick"
-USB_DEVICES = "CDC,MSC"
+
+# Turn off HID devices
+CIRCUITPY_USB_HID = 0
LONGINT_IMPL = NONE
diff --git a/ports/stm/mpconfigport.mk b/ports/stm/mpconfigport.mk
index bcecaa517..fe257fc50 100644
--- a/ports/stm/mpconfigport.mk
+++ b/ports/stm/mpconfigport.mk
@@ -8,6 +8,7 @@ ifeq ($(MCU_VARIANT),STM32F405xx)
CIRCUITPY_FRAMEBUFFERIO ?= 1
CIRCUITPY_RGBMATRIX ?= 1
CIRCUITPY_SDIOIO ?= 1
+ # Number of USB endpoint pairs.
USB_NUM_EP = 4
endif
@@ -23,6 +24,8 @@ ifeq ($(MCU_SERIES),F4)
CIRCUITPY_RTC ?= 0
CIRCUITPY_USB_MIDI ?= 0
CIRCUITPY_USB_HID ?= 0
+
+ USB_NUM_EP = 4
endif
ifeq ($(MCU_SERIES),H7)
@@ -40,6 +43,8 @@ ifeq ($(MCU_SERIES),H7)
CIRCUITPY_RTC ?= 0
CIRCUITPY_USB_HID ?= 0
CIRCUITPY_USB_MIDI ?= 0
+
+ USB_NUM_EP = 9
endif
ifeq ($(MCU_SERIES),F7)
@@ -56,4 +61,6 @@ ifeq ($(MCU_SERIES),F7)
CIRCUITPY_RTC ?= 0
CIRCUITPY_USB_HID ?= 0
CIRCUITPY_USB_MIDI ?= 0
+
+ USB_NUM_EP = 6
endif
diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk
index b8fe73eea..e13eca6ef 100644
--- a/py/circuitpy_mpconfig.mk
+++ b/py/circuitpy_mpconfig.mk
@@ -89,6 +89,9 @@ CFLAGS += -DCIRCUITPY_AUDIOMP3=$(CIRCUITPY_AUDIOMP3)
CIRCUITPY_BINASCII ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_BINASCII=$(CIRCUITPY_BINASCII)
+CIRCUITPY_BITBANG_APA102 ?= 0
+CFLAGS += -DCIRCUITPY_BITBANG_APA102=$(CIRCUITPY_BITBANG_APA102)
+
CIRCUITPY_BITBANGIO ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_BITBANGIO=$(CIRCUITPY_BITBANGIO)
@@ -100,6 +103,9 @@ CFLAGS += -DCIRCUITPY_BLEIO_HCI=$(CIRCUITPY_BLEIO_HCI)
CIRCUITPY_BLEIO ?= $(CIRCUITPY_BLEIO_HCI)
CFLAGS += -DCIRCUITPY_BLEIO=$(CIRCUITPY_BLEIO)
+CIRCUITPY_BLE_FILE_SERVICE ?= 0
+CFLAGS += -DCIRCUITPY_BLE_FILE_SERVICE=$(CIRCUITPY_BLE_FILE_SERVICE)
+
CIRCUITPY_BOARD ?= 1
CFLAGS += -DCIRCUITPY_BOARD=$(CIRCUITPY_BOARD)
@@ -127,6 +133,13 @@ CFLAGS += -DCIRCUITPY_COUNTIO=$(CIRCUITPY_COUNTIO)
CIRCUITPY_DISPLAYIO ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_DISPLAYIO=$(CIRCUITPY_DISPLAYIO)
+CIRCUITPY_DUALBANK ?= 0
+CFLAGS += -DCIRCUITPY_DUALBANK=$(CIRCUITPY_DUALBANK)
+
+# Enabled micropython.native decorator (experimental)
+CIRCUITPY_ENABLE_MPY_NATIVE ?= 0
+CFLAGS += -DCIRCUITPY_ENABLE_MPY_NATIVE=$(CIRCUITPY_ENABLE_MPY_NATIVE)
+
CIRCUITPY_ERRNO ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_ERRNO=$(CIRCUITPY_ERRNO)
@@ -179,6 +192,9 @@ CFLAGS += -DCIRCUITPY_MEMORYMONITOR=$(CIRCUITPY_MEMORYMONITOR)
CIRCUITPY_MICROCONTROLLER ?= 1
CFLAGS += -DCIRCUITPY_MICROCONTROLLER=$(CIRCUITPY_MICROCONTROLLER)
+CIRCUITPY_MSGPACK ?= $(CIRCUITPY_FULL_BUILD)
+CFLAGS += -DCIRCUITPY_MSGPACK=$(CIRCUITPY_MSGPACK)
+
CIRCUITPY_NEOPIXEL_WRITE ?= 1
CFLAGS += -DCIRCUITPY_NEOPIXEL_WRITE=$(CIRCUITPY_NEOPIXEL_WRITE)
@@ -192,8 +208,8 @@ CFLAGS += -DCIRCUITPY_NVM=$(CIRCUITPY_NVM)
CIRCUITPY_OS ?= 1
CFLAGS += -DCIRCUITPY_OS=$(CIRCUITPY_OS)
-CIRCUITPY_DUALBANK ?= 0
-CFLAGS += -DCIRCUITPY_DUALBANK=$(CIRCUITPY_DUALBANK)
+CIRCUITPY_PEW ?= 0
+CFLAGS += -DCIRCUITPY_PEW=$(CIRCUITPY_PEW)
CIRCUITPY_PIXELBUF ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_PIXELBUF=$(CIRCUITPY_PIXELBUF)
@@ -216,6 +232,11 @@ CFLAGS += -DCIRCUITPY_RANDOM=$(CIRCUITPY_RANDOM)
CIRCUITPY_RE ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_RE=$(CIRCUITPY_RE)
+# Should busio.I2C() check for pullups?
+# Some boards in combination with certain peripherals may not want this.
+CIRCUITPY_REQUIRE_I2C_PULLUPS ?= 1
+CFLAGS += -DCIRCUITPY_REQUIRE_I2C_PULLUPS=$(CIRCUITPY_REQUIRE_I2C_PULLUPS)
+
# CIRCUITPY_RP2PIO is handled in the raspberrypi tree.
# Only for rp2 chips.
# Assume not a rp2 build.
@@ -243,6 +264,18 @@ CFLAGS += -DCIRCUITPY_SDCARDIO=$(CIRCUITPY_SDCARDIO)
CIRCUITPY_SDIOIO ?= 0
CFLAGS += -DCIRCUITPY_SDIOIO=$(CIRCUITPY_SDIOIO)
+# Second USB CDC serial channel.
+CIRCUITPY_SERIAL2 ?=
+CFLAGS += -DCIRCUITPY_SERIAL2=$(CIRCUITPY_SERIAL2)
+
+# REPL over BLE
+CIRCUITPY_SERIAL_BLE ?= 0
+CFLAGS += -DCIRCUITPY_SERIAL_BLE=$(CIRCUITPY_SERIAL_BLE)
+
+# REPL over UART
+CIRCUITPY_SERIAL_UART ?= 0
+CFLAGS += -DCIRCUITPY_SERIAL_UART=$(CIRCUITPY_SERIAL_UART)
+
CIRCUITPY_SHARPDISPLAY ?= $(CIRCUITPY_FRAMEBUFFERIO)
CFLAGS += -DCIRCUITPY_SHARPDISPLAY=$(CIRCUITPY_SHARPDISPLAY)
@@ -285,36 +318,47 @@ CFLAGS += -DCIRCUITPY_UHEAP=$(CIRCUITPY_UHEAP)
CIRCUITPY_USB_HID ?= 1
CFLAGS += -DCIRCUITPY_USB_HID=$(CIRCUITPY_USB_HID)
-CIRCUITPY_USB_MIDI ?= 1
-CFLAGS += -DCIRCUITPY_USB_MIDI=$(CIRCUITPY_USB_MIDI)
+CIRCUITPY_USB_HID_CONSUMER ?= 1
+CFLAGS += -DCIRCUITPY_USB_HID_CONSUMER=$(CIRCUITPY_USB_HID_CONSUMER)
-CIRCUITPY_PEW ?= 0
-CFLAGS += -DCIRCUITPY_PEW=$(CIRCUITPY_PEW)
+CIRCUITPY_USB_HID_DIGITIZER ?= 0
+CFLAGS += -DCIRCUITPY_USB_HID_DIGITIZER=$(CIRCUITPY_USB_HID_DIGITIZER)
-# For debugging.
-CIRCUITPY_USTACK ?= 0
-CFLAGS += -DCIRCUITPY_USTACK=$(CIRCUITPY_USTACK)
+CIRCUITPY_USB_HID_GAMEPAD ?= 1
+CFLAGS += -DCIRCUITPY_USB_HID_GAMEPAD=$(CIRCUITPY_USB_HID_GAMEPAD)
-# Non-module conditionals
+CIRCUITPY_USB_HID_KEYBOARD ?= 1
+CFLAGS += -DCIRCUITPY_USB_HID_KEYBOARD=$(CIRCUITPY_USB_HID_KEYBOARD)
-CIRCUITPY_BITBANG_APA102 ?= 0
-CFLAGS += -DCIRCUITPY_BITBANG_APA102=$(CIRCUITPY_BITBANG_APA102)
+CIRCUITPY_USB_HID_MOUSE ?= 1
+CFLAGS += -DCIRCUITPY_USB_HID_MOUSE=$(CIRCUITPY_USB_HID_MOUSE)
-# Should busio.I2C() check for pullups?
-# Some boards in combination with certain peripherals may not want this.
-CIRCUITPY_REQUIRE_I2C_PULLUPS ?= 1
-CFLAGS += -DCIRCUITPY_REQUIRE_I2C_PULLUPS=$(CIRCUITPY_REQUIRE_I2C_PULLUPS)
+CIRCUITPY_USB_HID_SYS_CONTROL ?= 0
+CFLAGS += -DCIRCUITPY_USB_HID_CONTROL=$(CIRCUITPY_USB_HID_CONTROL)
-# REPL over BLE
-CIRCUITPY_SERIAL_BLE ?= 0
-CFLAGS += -DCIRCUITPY_SERIAL_BLE=$(CIRCUITPY_SERIAL_BLE)
+CIRCUITPY_USB_HID_XAC_COMPATIBLE_GAMEPAD ?= 0
+CFLAGS += -DCIRCUITPY_USB_HID_XAC_COMPATIBLE_GAMEPAD=$(CIRCUITPY_USB_HID_XAC_COMPATIBLE_GAMEPAD)
-CIRCUITPY_BLE_FILE_SERVICE ?= 0
-CFLAGS += -DCIRCUITPY_BLE_FILE_SERVICE=$(CIRCUITPY_BLE_FILE_SERVICE)
+CIRCUITPY_USB_MIDI ?= 1
+CFLAGS += -DCIRCUITPY_USB_MIDI=$(CIRCUITPY_USB_MIDI)
-# REPL over UART
-CIRCUITPY_SERIAL_UART ?= 0
-CFLAGS += -DCIRCUITPY_SERIAL_UART=$(CIRCUITPY_SERIAL_UART)
+CIRCUITPY_USB_MSC ?= 1
+CFLAGS += -DCIRCUITPY_USB_MSC=$(CIRCUITPY_USB_MSC)
+
+CIRCUITPY_USB_SERIAL ?= 1
+CFLAGS += -DCIRCUITPY_USB_SERIAL=$(CIRCUITPY_USB_MSC)
+
+ifndef USB_NUM_EP
+$(error "USB_NUM_EP (number of USB endpoint pairs)must be defined")
+endif
+
+# Secondary CDC is usually available if there are at least 8 endpoints.
+CIRCUITPY_USB_SERIAL2 ?= $(shell expr $(USB_NUM_EP) '>=' 8)
+CFLAGS += -DCIRCUITPY_USB_SERIAL2=$(CIRCUITPY_USB_SERIAL2)
+
+# For debugging.
+CIRCUITPY_USTACK ?= 0
+CFLAGS += -DCIRCUITPY_USTACK=$(CIRCUITPY_USTACK)
# ulab numerics library
CIRCUITPY_ULAB ?= $(CIRCUITPY_FULL_BUILD)
@@ -326,10 +370,3 @@ CFLAGS += -DCIRCUITPY_WATCHDOG=$(CIRCUITPY_WATCHDOG)
CIRCUITPY_WIFI ?= 0
CFLAGS += -DCIRCUITPY_WIFI=$(CIRCUITPY_WIFI)
-
-# Enabled micropython.native decorator (experimental)
-CIRCUITPY_ENABLE_MPY_NATIVE ?= 0
-CFLAGS += -DCIRCUITPY_ENABLE_MPY_NATIVE=$(CIRCUITPY_ENABLE_MPY_NATIVE)
-
-CIRCUITPY_MSGPACK ?= $(CIRCUITPY_FULL_BUILD)
-CFLAGS += -DCIRCUITPY_MSGPACK=$(CIRCUITPY_MSGPACK)
diff --git a/supervisor/shared/usb/tusb_config.h b/supervisor/shared/usb/tusb_config.h
index 15d9fabaf..0e70367d0 100644
--- a/supervisor/shared/usb/tusb_config.h
+++ b/supervisor/shared/usb/tusb_config.h
@@ -61,10 +61,15 @@
// DEVICE CONFIGURATION
//--------------------------------------------------------------------+
-#define CFG_TUD_ENDOINT0_SIZE 64
+#define CFG_TUD_ENDPOINT0_SIZE 64
//------------- CLASS -------------//
+
+// Could be 2 if secondary CDC channel requested.
+#ifndef CFG_TUD_CDC
#define CFG_TUD_CDC 1
+#endif
+
#define CFG_TUD_MSC 1
#define CFG_TUD_HID CIRCUITPY_USB_HID
#define CFG_TUD_MIDI CIRCUITPY_USB_MIDI
diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk
index a59e99e3d..8fd32fa0b 100644
--- a/supervisor/supervisor.mk
+++ b/supervisor/supervisor.mk
@@ -14,23 +14,15 @@ SRC_SUPERVISOR = \
supervisor/shared/tick.c \
supervisor/shared/translate.c
-ifndef $(NO_USB)
- NO_USB = $(wildcard supervisor/usb.c)
-endif
+NO_USB ?= $(wildcard supervisor/usb.c)
-ifndef INTERNAL_FLASH_FILESYSTEM
-INTERNAL_FLASH_FILESYSTEM = 0
-endif
+INTERNAL_FLASH_FILESYSTEM ?= 0
CFLAGS += -DINTERNAL_FLASH_FILESYSTEM=$(INTERNAL_FLASH_FILESYSTEM)
-ifndef QSPI_FLASH_FILESYSTEM
-QSPI_FLASH_FILESYSTEM = 0
-endif
+QSPI_FLASH_FILESYSTEM ?= 0
CFLAGS += -DQSPI_FLASH_FILESYSTEM=$(QSPI_FLASH_FILESYSTEM)
-ifndef SPI_FLASH_FILESYSTEM
SPI_FLASH_FILESYSTEM = 0
-endif
CFLAGS += -DSPI_FLASH_FILESYSTEM=$(SPI_FLASH_FILESYSTEM)
ifeq ($(CIRCUITPY_BLEIO),1)
@@ -115,66 +107,78 @@ ifeq ($(CIRCUITPY_DISPLAYIO), 1)
SUPERVISOR_O += $(BUILD)/autogen_display_resources.o
endif
endif
-ifndef USB_INTERFACE_NAME
-USB_INTERFACE_NAME = "CircuitPython"
+
+USB_INTERFACE_NAME ?= "CircuitPython"
+
+ifneq ($(USB_VID),)
+CFLAGS += -DUSB_VID=$(USB_VID)
+CFLAGS += -DSUB_PID=$(USB_PID)
+CFLAGS += -DUSB_MANUFACTURER=$(USB_MANUFACTURER)
+CFLAGS += -DUSB_PRODUCT=$(USB_PRODUCT)
endif
-USB_DEVICES_COMPUTED := CDC,MSC
+USB_DEVICES =
+ifeq ($(CIRCUITPY_USB_HID),1)
+USB_DEVICES += HID
+endif
ifeq ($(CIRCUITPY_USB_MIDI),1)
-USB_DEVICES_COMPUTED := $(USB_DEVICES_COMPUTED),AUDIO
+USB_DEVICES += AUDIO
endif
-ifeq ($(CIRCUITPY_USB_HID),1)
-USB_DEVICES_COMPUTED := $(USB_DEVICES_COMPUTED),HID
+ifeq ($(CIRCUITPY_USB_MSC),1)
+USB_DEVICES += MSC
endif
-USB_DEVICES ?= "$(USB_DEVICES_COMPUTED)"
-
-ifndef USB_HID_DEVICES
-USB_HID_DEVICES = "KEYBOARD,MOUSE,CONSUMER,GAMEPAD"
+ifeq ($(CIRCUITPY_USB_SERIAL),1)
+USB_DEVICES += CDC
endif
-
-ifndef USB_HIGHSPEED
-USB_HIGHSPEED = 0
+ifeq ($(CIRCUITPY_USB_SERIAL2),1)
+# Inform TinyUSB there are two CDC devices.
+CFLAGS += -DCFG_TUD_CDC=2
+USB_DEVICES += CDC2
endif
-ifndef USB_CDC_EP_NUM_NOTIFICATION
-USB_CDC_EP_NUM_NOTIFICATION = 0
+USB_HID_DEVICES =
+ifeq ($(CIRCUITPY_USB_HID_CONSUMER),1)
+USB_HID_DEVICES += CONSUMER
endif
-
-ifndef USB_CDC_EP_NUM_DATA_OUT
-USB_CDC_EP_NUM_DATA_OUT = 0
+ifeq ($(CIRCUITPY_USB_HID_DIGITIZER),1)
+USB_HID_DEVICES += DIGITIZER
endif
-
-ifndef USB_CDC_EP_NUM_DATA_IN
-USB_CDC_EP_NUM_DATA_IN = 0
+ifeq ($(CIRCUITPY_USB_HID_GAMEPAD),1)
+USB_HID_DEVICES += GAMEPAD
endif
-
-ifndef USB_MSC_EP_NUM_OUT
-USB_MSC_EP_NUM_OUT = 0
+ifeq ($(CIRCUITPY_USB_HID_KEYBOARD),1)
+USB_HID_DEVICES += KEYBOARD
endif
-
-ifndef USB_MSC_EP_NUM_IN
-USB_MSC_EP_NUM_IN = 0
+ifeq ($(CIRCUITPY_USB_HID_MOUSE),1)
+USB_HID_DEVICES += MOUSE
endif
-
-ifndef USB_HID_EP_NUM_OUT
-USB_HID_EP_NUM_OUT = 0
+ifeq ($(CIRCUITPY_USB_HID_SYS_CONTROL),1)
+USB_HID_DEVICES += SYS_CONTROL
endif
-
-ifndef USB_HID_EP_NUM_IN
-USB_HID_EP_NUM_IN = 0
+ifeq ($(CIRCUITPY_USB_HID_XAC_COMPATIBLE_GAMEPAD),1)
+USB_HID_DEVICES += XAC_COMPATIBLE_GAMEPAD
endif
-ifndef USB_MIDI_EP_NUM_OUT
-USB_MIDI_EP_NUM_OUT = 0
+# RAW is not compatible with other HID devices.
+ifeq ($(CIRCUITPY_USB_HID_RAW),1)
+ ifneq ($(CIRCUITPY_USB_HID_DEVICES,)
+ $(error HID RAW must not be combined with other HID devices)
+ endif
+USB_HID_DEVICES += MOUSE
endif
-ifndef USB_MIDI_EP_NUM_IN
-USB_MIDI_EP_NUM_IN = 0
-endif
+USB_HIGHSPEED ?= 0
-ifndef USB_NUM_EP
-USB_NUM_EP = 0
-endif
+USB_CDC_EP_NUM_NOTIFICATION ?= 0
+USB_CDC_EP_NUM_DATA_OUT ?= 0
+USB_CDC_EP_NUM_DATA_IN ?= 0
+USB_MSC_EP_NUM_OUT ?= 0
+USB_MSC_EP_NUM_IN ?= 0
+USB_HID_EP_NUM_OUT ?= 0
+USB_HID_EP_NUM_IN ?= 0
+USB_MIDI_EP_NUM_OUT ?= 0
+USB_MIDI_EP_NUM_IN ?= 0
+USB_NUM_EP ?= 0
USB_DESCRIPTOR_ARGS = \
--manufacturer $(USB_MANUFACTURER)\
@@ -183,8 +187,8 @@ USB_DESCRIPTOR_ARGS = \
--pid $(USB_PID)\
--serial_number_length $(USB_SERIAL_NUMBER_LENGTH)\
--interface_name $(USB_INTERFACE_NAME)\
- --devices $(USB_DEVICES)\
- --hid_devices $(USB_HID_DEVICES)\
+ --devices "$(USB_DEVICES)"\
+ --hid_devices "$(USB_HID_DEVICES)"\
--max_ep $(USB_NUM_EP) \
--cdc_ep_num_notification $(USB_CDC_EP_NUM_NOTIFICATION)\
--cdc_ep_num_data_out $(USB_CDC_EP_NUM_DATA_OUT)\
diff --git a/tools/gen_usb_descriptor.py b/tools/gen_usb_descriptor.py
index 672f09c88..199cdf9cf 100644
--- a/tools/gen_usb_descriptor.py
+++ b/tools/gen_usb_descriptor.py
@@ -12,60 +12,98 @@ sys.path.append("../../tools/usb_descriptor")
from adafruit_usb_descriptor import audio, audio10, cdc, hid, midi, msc, standard, util
import hid_report_descriptors
-DEFAULT_INTERFACE_NAME = 'CircuitPython'
-ALL_DEVICES='CDC,MSC,AUDIO,HID'
-ALL_DEVICES_SET=frozenset(ALL_DEVICES.split(','))
-DEFAULT_DEVICES='CDC,MSC,AUDIO,HID'
-
-ALL_HID_DEVICES='KEYBOARD,MOUSE,CONSUMER,SYS_CONTROL,GAMEPAD,DIGITIZER,XAC_COMPATIBLE_GAMEPAD,RAW'
-ALL_HID_DEVICES_SET=frozenset(ALL_HID_DEVICES.split(','))
+DEFAULT_INTERFACE_NAME = "CircuitPython"
+ALL_DEVICES = "CDC CDC2 MSC AUDIO HID"
+ALL_DEVICES_SET = frozenset(ALL_DEVICES.split())
+DEFAULT_DEVICES = "CDC MSC AUDIO HID"
+
+ALL_HID_DEVICES = (
+ "KEYBOARD MOUSE CONSUMER SYS_CONTROL GAMEPAD DIGITIZER XAC_COMPATIBLE_GAMEPAD RAW"
+)
+ALL_HID_DEVICES_SET = frozenset(ALL_HID_DEVICES.split())
# Digitizer works on Linux but conflicts with mouse, so omit it.
-DEFAULT_HID_DEVICES='KEYBOARD,MOUSE,CONSUMER,GAMEPAD'
-
-parser = argparse.ArgumentParser(description='Generate USB descriptors.')
-parser.add_argument('--highspeed', default=False, action='store_true',
- help='descriptor for highspeed device')
-parser.add_argument('--manufacturer', type=str,
- help='manufacturer of the device')
-parser.add_argument('--product', type=str,
- help='product name of the device')
-parser.add_argument('--vid', type=lambda x: int(x, 16),
- help='vendor id')
-parser.add_argument('--pid', type=lambda x: int(x, 16),
- help='product id')
-parser.add_argument('--serial_number_length', type=int, default=32,
- help='length needed for the serial number in digits')
-parser.add_argument('--devices', type=lambda l: tuple(l.split(',')), default=DEFAULT_DEVICES,
- help='devices to include in descriptor (AUDIO includes MIDI support)')
-parser.add_argument('--hid_devices', type=lambda l: tuple(l.split(',')), default=DEFAULT_HID_DEVICES,
- help='HID devices to include in HID report descriptor')
-parser.add_argument('--interface_name', type=str,
- help='The name/prefix to use in the interface descriptions',
- default=DEFAULT_INTERFACE_NAME)
-parser.add_argument('--no-renumber_endpoints', dest='renumber_endpoints', action='store_false',
- help='use to not renumber endpoint')
-parser.add_argument('--cdc_ep_num_notification', type=int, default=0,
- help='endpoint number of CDC NOTIFICATION')
-parser.add_argument('--cdc_ep_num_data_out', type=int, default=0,
- help='endpoint number of CDC DATA OUT')
-parser.add_argument('--cdc_ep_num_data_in', type=int, default=0,
- help='endpoint number of CDC DATA IN')
-parser.add_argument('--msc_ep_num_out', type=int, default=0,
- help='endpoint number of MSC OUT')
-parser.add_argument('--msc_ep_num_in', type=int, default=0,
- help='endpoint number of MSC IN')
-parser.add_argument('--hid_ep_num_out', type=int, default=0,
- help='endpoint number of HID OUT')
-parser.add_argument('--hid_ep_num_in', type=int, default=0,
- help='endpoint number of HID IN')
-parser.add_argument('--midi_ep_num_out', type=int, default=0,
- help='endpoint number of MIDI OUT')
-parser.add_argument('--midi_ep_num_in', type=int, default=0,
- help='endpoint number of MIDI IN')
-parser.add_argument('--max_ep', type=int, default=0,
- help='total number of endpoints available')
-parser.add_argument('--output_c_file', type=argparse.FileType('w', encoding='UTF-8'), required=True)
-parser.add_argument('--output_h_file', type=argparse.FileType('w', encoding='UTF-8'), required=True)
+DEFAULT_HID_DEVICES = "KEYBOARD MOUSE CONSUMER GAMEPAD"
+
+parser = argparse.ArgumentParser(description="Generate USB descriptors.")
+parser.add_argument(
+ "--highspeed",
+ default=False,
+ action="store_true",
+ help="descriptor for highspeed device",
+)
+parser.add_argument("--manufacturer", type=str, help="manufacturer of the device")
+parser.add_argument("--product", type=str, help="product name of the device")
+parser.add_argument("--vid", type=lambda x: int(x, 16), help="vendor id")
+parser.add_argument("--pid", type=lambda x: int(x, 16), help="product id")
+parser.add_argument(
+ "--serial_number_length",
+ type=int,
+ default=32,
+ help="length needed for the serial number in digits",
+)
+parser.add_argument(
+ "--devices",
+ type=lambda l: tuple(l.split()),
+ default=DEFAULT_DEVICES,
+ help="devices to include in descriptor (AUDIO includes MIDI support)",
+)
+parser.add_argument(
+ "--hid_devices",
+ type=lambda l: tuple(l.split()),
+ default=DEFAULT_HID_DEVICES,
+ help="HID devices to include in HID report descriptor",
+)
+parser.add_argument(
+ "--interface_name",
+ type=str,
+ help="The name/prefix to use in the interface descriptions",
+ default=DEFAULT_INTERFACE_NAME,
+)
+parser.add_argument(
+ "--no-renumber_endpoints",
+ dest="renumber_endpoints",
+ action="store_false",
+ help="use to not renumber endpoint",
+)
+parser.add_argument(
+ "--cdc_ep_num_notification",
+ type=int,
+ default=0,
+ help="endpoint number of CDC NOTIFICATION",
+)
+parser.add_argument(
+ "--cdc_ep_num_data_out", type=int, default=0, help="endpoint number of CDC DATA OUT"
+)
+parser.add_argument(
+ "--cdc_ep_num_data_in", type=int, default=0, help="endpoint number of CDC DATA IN"
+)
+parser.add_argument(
+ "--msc_ep_num_out", type=int, default=0, help="endpoint number of MSC OUT"
+)
+parser.add_argument(
+ "--msc_ep_num_in", type=int, default=0, help="endpoint number of MSC IN"
+)
+parser.add_argument(
+ "--hid_ep_num_out", type=int, default=0, help="endpoint number of HID OUT"
+)
+parser.add_argument(
+ "--hid_ep_num_in", type=int, default=0, help="endpoint number of HID IN"
+)
+parser.add_argument(
+ "--midi_ep_num_out", type=int, default=0, help="endpoint number of MIDI OUT"
+)
+parser.add_argument(
+ "--midi_ep_num_in", type=int, default=0, help="endpoint number of MIDI IN"
+)
+parser.add_argument(
+ "--max_ep", type=int, default=0, help="total number of endpoints available"
+)
+parser.add_argument(
+ "--output_c_file", type=argparse.FileType("w", encoding="UTF-8"), required=True
+)
+parser.add_argument(
+ "--output_h_file", type=argparse.FileType("w", encoding="UTF-8"), required=True
+)
args = parser.parse_args()
@@ -77,8 +115,17 @@ unknown_hid_devices = list(frozenset(args.hid_devices) - ALL_HID_DEVICES_SET)
if unknown_hid_devices:
raise ValueError("Unknown HID devices(s)", unknown_hid_devices)
+include_cdc = "CDC" in args.devices
+include_cdc2 = "CDC2" in args.devices
+include_msc = "MSC" in args.devices
+include_hid = "HID" in args.devices
+include_audio = "AUDIO" in args.devices
+
+if not include_cdc and include_cdc2:
+ raise ValueError("CDC2 requested without CDC")
+
if not args.renumber_endpoints:
- if 'CDC' in args.devices:
+ if include_cdc:
if args.cdc_ep_num_notification == 0:
raise ValueError("CDC notification endpoint number must not be 0")
elif args.cdc_ep_num_data_out == 0:
@@ -86,32 +133,37 @@ if not args.renumber_endpoints:
elif args.cdc_ep_num_data_in == 0:
raise ValueError("CDC data IN endpoint number must not be 0")
- if 'MSC' in args.devices:
+ if include_cdc2:
+ raise ValueError("Second CDC not supported without renumbering endpoints")
+
+ if include_msc:
if args.msc_ep_num_out == 0:
raise ValueError("MSC endpoint OUT number must not be 0")
- elif args.msc_ep_num_in == 0:
+ elif args.msc_ep_num_in == 0:
raise ValueError("MSC endpoint IN number must not be 0")
- if 'HID' in args.devices:
+ if include_hid:
if args.args.hid_ep_num_out == 0:
raise ValueError("HID endpoint OUT number must not be 0")
- elif args.hid_ep_num_in == 0:
+ elif args.hid_ep_num_in == 0:
raise ValueError("HID endpoint IN number must not be 0")
- if 'AUDIO' in args.devices:
+ if include_audio:
if args.args.midi_ep_num_out == 0:
raise ValueError("MIDI endpoint OUT number must not be 0")
- elif args.midi_ep_num_in == 0:
+ elif args.midi_ep_num_in == 0:
raise ValueError("MIDI endpoint IN number must not be 0")
+
class StringIndex:
"""Assign a monotonically increasing index to each unique string. Start with 0."""
+
string_to_index = {}
index_to_variable = {}
strings = []
@classmethod
- def index(cls, string, *, variable_name = None):
+ def index(cls, string, *, variable_name=None):
if string in cls.string_to_index:
idx = cls.string_to_index[string]
if not cls.index_to_variable[idx]:
@@ -129,11 +181,12 @@ class StringIndex:
return cls.strings
-
# langid must be the 0th string descriptor
LANGID_INDEX = StringIndex.index("\u0409", variable_name="language_id")
assert LANGID_INDEX == 0
-SERIAL_NUMBER_INDEX = StringIndex.index("S" * args.serial_number_length, variable_name="usb_serial_number")
+SERIAL_NUMBER_INDEX = StringIndex.index(
+ "S" * args.serial_number_length, variable_name="usb_serial_number"
+)
device = standard.DeviceDescriptor(
description="top",
@@ -141,212 +194,267 @@ device = standard.DeviceDescriptor(
idProduct=args.pid,
iManufacturer=StringIndex.index(args.manufacturer),
iProduct=StringIndex.index(args.product),
- iSerialNumber=SERIAL_NUMBER_INDEX)
+ iSerialNumber=SERIAL_NUMBER_INDEX,
+)
# Interface numbers are interface-set local and endpoints are interface local
# until util.join_interfaces renumbers them.
-cdc_union = cdc.Union(
- description="CDC comm",
- bMasterInterface=0x00, # Adjust this after interfaces are renumbered.
- bSlaveInterface_list=[0x01]) # Adjust this after interfaces are renumbered.
-
-cdc_call_management = cdc.CallManagement(
- description="CDC comm",
- bmCapabilities=0x01,
- bDataInterface=0x01) # Adjust this after interfaces are renumbered.
-
-cdc_comm_interface = standard.InterfaceDescriptor(
- description="CDC comm",
- bInterfaceClass=cdc.CDC_CLASS_COMM, # Communications Device Class
- bInterfaceSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model
- bInterfaceProtocol=cdc.CDC_PROTOCOL_NONE,
- iInterface=StringIndex.index("{} CDC control".format(args.interface_name)),
- subdescriptors=[
- cdc.Header(
- description="CDC comm",
- bcdCDC=0x0110),
- cdc_call_management,
- cdc.AbstractControlManagement(
- description="CDC comm",
- bmCapabilities=0x02),
- cdc_union,
- standard.EndpointDescriptor(
- description="CDC comm in",
- bEndpointAddress=args.cdc_ep_num_notification | standard.EndpointDescriptor.DIRECTION_IN,
- bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT,
- wMaxPacketSize=0x0040,
- bInterval=0x10)
- ])
-
-cdc_data_interface = standard.InterfaceDescriptor(
- description="CDC data",
- bInterfaceClass=cdc.CDC_CLASS_DATA,
- iInterface=StringIndex.index("{} CDC data".format(args.interface_name)),
- subdescriptors=[
- standard.EndpointDescriptor(
- description="CDC data out",
- bEndpointAddress=args.cdc_ep_num_data_out | standard.EndpointDescriptor.DIRECTION_OUT,
- bmAttributes=standard.EndpointDescriptor.TYPE_BULK,
- bInterval=0,
- wMaxPacketSize=512 if args.highspeed else 64),
- standard.EndpointDescriptor(
- description="CDC data in",
- bEndpointAddress=args.cdc_ep_num_data_in | standard.EndpointDescriptor.DIRECTION_IN,
- bmAttributes=standard.EndpointDescriptor.TYPE_BULK,
- bInterval=0,
- wMaxPacketSize=512 if args.highspeed else 64),
- ])
-
-cdc_interfaces = [cdc_comm_interface, cdc_data_interface]
-
-msc_interfaces = [
- standard.InterfaceDescriptor(
- description="MSC",
- bInterfaceClass=msc.MSC_CLASS,
- bInterfaceSubClass=msc.MSC_SUBCLASS_TRANSPARENT,
- bInterfaceProtocol=msc.MSC_PROTOCOL_BULK,
- iInterface=StringIndex.index("{} Mass Storage".format(args.interface_name)),
+
+def make_cdc_union(name):
+ return cdc.Union(
+ description="{} comm".format(name),
+ bMasterInterface=0x00, # Adjust this after interfaces are renumbered.
+ bSlaveInterface_list=[0x01],
+ ) # Adjust this after interfaces are renumbered.
+
+
+def make_cdc_call_management(name):
+ return cdc.CallManagement(
+ description="{} comm".format(name), bmCapabilities=0x01, bDataInterface=0x01
+ ) # Adjust this after interfaces are renumbered.
+
+
+def make_cdc_comm_interface(name, cdc_union):
+ return standard.InterfaceDescriptor(
+ description="{} comm".format(name),
+ bInterfaceClass=cdc.CDC_CLASS_COMM, # Communications Device Class
+ bInterfaceSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model
+ bInterfaceProtocol=cdc.CDC_PROTOCOL_NONE,
+ iInterface=StringIndex.index("{} {} control".format(args.interface_name, name)),
+ subdescriptors=[
+ cdc.Header(description="{} comm".format(name), bcdCDC=0x0110),
+ cdc_call_management,
+ cdc.AbstractControlManagement(
+ description="{} comm".format(name), bmCapabilities=0x02
+ ),
+ cdc_union,
+ standard.EndpointDescriptor(
+ description="{} comm in".format(name),
+ bEndpointAddress=args.cdc_ep_num_notification
+ | standard.EndpointDescriptor.DIRECTION_IN,
+ bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT,
+ wMaxPacketSize=0x0040,
+ bInterval=0x10,
+ ),
+ ],
+ )
+
+
+def make_cdc_data_interface(name):
+ return standard.InterfaceDescriptor(
+ description="{} data".format(name),
+ bInterfaceClass=cdc.CDC_CLASS_DATA,
+ iInterface=StringIndex.index("{} {} data".format(args.interface_name, name)),
subdescriptors=[
standard.EndpointDescriptor(
- description="MSC in",
- bEndpointAddress=args.msc_ep_num_in | standard.EndpointDescriptor.DIRECTION_IN,
+ description="{} data out".format(name),
+ bEndpointAddress=args.cdc_ep_num_data_out
+ | standard.EndpointDescriptor.DIRECTION_OUT,
bmAttributes=standard.EndpointDescriptor.TYPE_BULK,
bInterval=0,
- wMaxPacketSize=512 if args.highspeed else 64),
+ wMaxPacketSize=512 if args.highspeed else 64,
+ ),
standard.EndpointDescriptor(
- description="MSC out",
- bEndpointAddress=(args.msc_ep_num_out | standard.EndpointDescriptor.DIRECTION_OUT),
+ description="{} data in".format(name),
+ bEndpointAddress=args.cdc_ep_num_data_in
+ | standard.EndpointDescriptor.DIRECTION_IN,
bmAttributes=standard.EndpointDescriptor.TYPE_BULK,
bInterval=0,
- wMaxPacketSize=512 if args.highspeed else 64),
- ]
+ wMaxPacketSize=512 if args.highspeed else 64,
+ ),
+ ],
)
-]
-
-# When there's only one hid_device, it shouldn't have a report id.
-# Otherwise, report ids are assigned sequentially:
-# args.hid_devices[0] has report_id 1
-# args.hid_devices[1] has report_id 2
-# etc.
-report_ids = {}
-if len(args.hid_devices) == 1:
- name = args.hid_devices[0]
- combined_hid_report_descriptor = hid.ReportDescriptor(
- description=name,
- report_descriptor=bytes(hid_report_descriptors.REPORT_DESCRIPTOR_FUNCTIONS[name](0)))
- report_ids[name] = 0
-else:
- report_id = 1
- concatenated_descriptors = bytearray()
- for name in args.hid_devices:
- concatenated_descriptors.extend(
- bytes(hid_report_descriptors.REPORT_DESCRIPTOR_FUNCTIONS[name](report_id)))
- report_ids[name] = report_id
- report_id += 1
- combined_hid_report_descriptor = hid.ReportDescriptor(
- description="MULTIDEVICE",
- report_descriptor=bytes(concatenated_descriptors))
-
-# ASF4 expects keyboard and generic devices to have both in and out endpoints,
-# and will fail (possibly silently) if both are not supplied.
-hid_endpoint_in_descriptor = standard.EndpointDescriptor(
- description="HID in",
- bEndpointAddress=args.hid_ep_num_in | standard.EndpointDescriptor.DIRECTION_IN,
- bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT,
- bInterval=8)
-
-hid_endpoint_out_descriptor = standard.EndpointDescriptor(
- description="HID out",
- bEndpointAddress=args.hid_ep_num_out | standard.EndpointDescriptor.DIRECTION_OUT,
- bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT,
- bInterval=8)
-
-hid_interfaces = [
- standard.InterfaceDescriptor(
- description="HID Multiple Devices",
- bInterfaceClass=hid.HID_CLASS,
- bInterfaceSubClass=hid.HID_SUBCLASS_NOBOOT,
- bInterfaceProtocol=hid.HID_PROTOCOL_NONE,
- iInterface=StringIndex.index("{} HID".format(args.interface_name)),
- subdescriptors=[
- hid.HIDDescriptor(
- description="HID",
- wDescriptorLength=len(bytes(combined_hid_report_descriptor))),
- hid_endpoint_in_descriptor,
- hid_endpoint_out_descriptor,
- ]
- ),
+if include_cdc:
+ cdc_union = make_cdc_union("CDC")
+ cdc_call_management = make_cdc_call_management("CDC")
+ cdc_comm_interface = make_cdc_comm_interface("CDC", cdc_union)
+ cdc_data_interface = make_cdc_data_interface("CDC")
+
+ cdc_interfaces = [cdc_comm_interface, cdc_data_interface]
+
+if include_cdc2:
+ cdc2_union = make_cdc_union("CDC2")
+ cdc2_call_management = make_cdc_call_management("CDC2")
+ cdc2_comm_interface = make_cdc_comm_interface("CDC2", cdc2_union)
+ cdc2_data_interface = make_cdc_data_interface("CDC2")
+
+ cdc2_interfaces = [cdc2_comm_interface, cdc2_data_interface]
+
+if include_msc:
+ msc_interfaces = [
+ standard.InterfaceDescriptor(
+ description="MSC",
+ bInterfaceClass=msc.MSC_CLASS,
+ bInterfaceSubClass=msc.MSC_SUBCLASS_TRANSPARENT,
+ bInterfaceProtocol=msc.MSC_PROTOCOL_BULK,
+ iInterface=StringIndex.index("{} Mass Storage".format(args.interface_name)),
+ subdescriptors=[
+ standard.EndpointDescriptor(
+ description="MSC in",
+ bEndpointAddress=args.msc_ep_num_in
+ | standard.EndpointDescriptor.DIRECTION_IN,
+ bmAttributes=standard.EndpointDescriptor.TYPE_BULK,
+ bInterval=0,
+ wMaxPacketSize=512 if args.highspeed else 64,
+ ),
+ standard.EndpointDescriptor(
+ description="MSC out",
+ bEndpointAddress=(
+ args.msc_ep_num_out | standard.EndpointDescriptor.DIRECTION_OUT
+ ),
+ bmAttributes=standard.EndpointDescriptor.TYPE_BULK,
+ bInterval=0,
+ wMaxPacketSize=512 if args.highspeed else 64,
+ ),
+ ],
+ )
]
-# Audio!
-# In and out here are relative to CircuitPython
-
-# USB OUT -> midi_in_jack_emb -> midi_out_jack_ext -> CircuitPython
-midi_in_jack_emb = midi.InJackDescriptor(
- description="MIDI PC -> {}".format(args.interface_name),
- bJackType=midi.JACK_TYPE_EMBEDDED,
- iJack=StringIndex.index("{} usb_midi.ports[0]".format(args.interface_name)))
-midi_out_jack_ext = midi.OutJackDescriptor(
- description="MIDI data out to user code.",
- bJackType=midi.JACK_TYPE_EXTERNAL,
- input_pins=[(midi_in_jack_emb, 1)],
- iJack=0)
-
-# USB IN <- midi_out_jack_emb <- midi_in_jack_ext <- CircuitPython
-midi_in_jack_ext = midi.InJackDescriptor(
- description="MIDI data in from user code.",
- bJackType=midi.JACK_TYPE_EXTERNAL,
- iJack=0)
-midi_out_jack_emb = midi.OutJackDescriptor(
- description="MIDI PC <- {}".format(args.interface_name),
- bJackType=midi.JACK_TYPE_EMBEDDED,
- input_pins=[(midi_in_jack_ext, 1)],
- iJack=StringIndex.index("{} usb_midi.ports[1]".format(args.interface_name)))
-
-
-audio_midi_interface = standard.InterfaceDescriptor(
- description="Midi goodness",
- bInterfaceClass=audio.AUDIO_CLASS_DEVICE,
- bInterfaceSubClass=audio.AUDIO_SUBCLASS_MIDI_STREAMING,
- bInterfaceProtocol=audio.AUDIO_PROTOCOL_V1,
- iInterface=StringIndex.index("{} MIDI".format(args.interface_name)),
- subdescriptors=[
- midi.Header(
- jacks_and_elements=[
- midi_in_jack_emb,
- midi_in_jack_ext,
- midi_out_jack_emb,
- midi_out_jack_ext
+
+if include_hid:
+ # When there's only one hid_device, it shouldn't have a report id.
+ # Otherwise, report ids are assigned sequentially:
+ # args.hid_devices[0] has report_id 1
+ # args.hid_devices[1] has report_id 2
+ # etc.
+
+ report_ids = {}
+
+ if len(args.hid_devices) == 1:
+ name = args.hid_devices[0]
+ combined_hid_report_descriptor = hid.ReportDescriptor(
+ description=name,
+ report_descriptor=bytes(
+ hid_report_descriptors.REPORT_DESCRIPTOR_FUNCTIONS[name](0)
+ ),
+ )
+ report_ids[name] = 0
+ else:
+ report_id = 1
+ concatenated_descriptors = bytearray()
+ for name in args.hid_devices:
+ concatenated_descriptors.extend(
+ bytes(
+ hid_report_descriptors.REPORT_DESCRIPTOR_FUNCTIONS[name](report_id)
+ )
+ )
+ report_ids[name] = report_id
+ report_id += 1
+ combined_hid_report_descriptor = hid.ReportDescriptor(
+ description="MULTIDEVICE", report_descriptor=bytes(concatenated_descriptors)
+ )
+
+ # ASF4 expects keyboard and generic devices to have both in and out endpoints,
+ # and will fail (possibly silently) if both are not supplied.
+ hid_endpoint_in_descriptor = standard.EndpointDescriptor(
+ description="HID in",
+ bEndpointAddress=args.hid_ep_num_in | standard.EndpointDescriptor.DIRECTION_IN,
+ bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT,
+ bInterval=8,
+ )
+
+ hid_endpoint_out_descriptor = standard.EndpointDescriptor(
+ description="HID out",
+ bEndpointAddress=args.hid_ep_num_out
+ | standard.EndpointDescriptor.DIRECTION_OUT,
+ bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT,
+ bInterval=8,
+ )
+
+ hid_interfaces = [
+ standard.InterfaceDescriptor(
+ description="HID Multiple Devices",
+ bInterfaceClass=hid.HID_CLASS,
+ bInterfaceSubClass=hid.HID_SUBCLASS_NOBOOT,
+ bInterfaceProtocol=hid.HID_PROTOCOL_NONE,
+ iInterface=StringIndex.index("{} HID".format(args.interface_name)),
+ subdescriptors=[
+ hid.HIDDescriptor(
+ description="HID",
+ wDescriptorLength=len(bytes(combined_hid_report_descriptor)),
+ ),
+ hid_endpoint_in_descriptor,
+ hid_endpoint_out_descriptor,
],
),
- standard.EndpointDescriptor(
- description="MIDI data out to {}".format(args.interface_name),
- bEndpointAddress=args.midi_ep_num_out | standard.EndpointDescriptor.DIRECTION_OUT,
- bmAttributes=standard.EndpointDescriptor.TYPE_BULK,
- bInterval=0,
- wMaxPacketSize=512 if args.highspeed else 64),
- midi.DataEndpointDescriptor(baAssocJack=[midi_in_jack_emb]),
- standard.EndpointDescriptor(
- description="MIDI data in from {}".format(args.interface_name),
- bEndpointAddress=args.midi_ep_num_in | standard.EndpointDescriptor.DIRECTION_IN,
- bmAttributes=standard.EndpointDescriptor.TYPE_BULK,
- bInterval = 0x0,
- wMaxPacketSize=512 if args.highspeed else 64),
- midi.DataEndpointDescriptor(baAssocJack=[midi_out_jack_emb]),
- ])
-
-cs_ac_interface = audio10.AudioControlInterface(
+ ]
+
+if include_audio:
+ # Audio!
+ # In and out here are relative to CircuitPython
+
+ # USB OUT -> midi_in_jack_emb -> midi_out_jack_ext -> CircuitPython
+ midi_in_jack_emb = midi.InJackDescriptor(
+ description="MIDI PC -> {}".format(args.interface_name),
+ bJackType=midi.JACK_TYPE_EMBEDDED,
+ iJack=StringIndex.index("{} usb_midi.ports[0]".format(args.interface_name)),
+ )
+ midi_out_jack_ext = midi.OutJackDescriptor(
+ description="MIDI data out to user code.",
+ bJackType=midi.JACK_TYPE_EXTERNAL,
+ input_pins=[(midi_in_jack_emb, 1)],
+ iJack=0,
+ )
+
+ # USB IN <- midi_out_jack_emb <- midi_in_jack_ext <- CircuitPython
+ midi_in_jack_ext = midi.InJackDescriptor(
+ description="MIDI data in from user code.",
+ bJackType=midi.JACK_TYPE_EXTERNAL,
+ iJack=0,
+ )
+ midi_out_jack_emb = midi.OutJackDescriptor(
+ description="MIDI PC <- {}".format(args.interface_name),
+ bJackType=midi.JACK_TYPE_EMBEDDED,
+ input_pins=[(midi_in_jack_ext, 1)],
+ iJack=StringIndex.index("{} usb_midi.ports[1]".format(args.interface_name)),
+ )
+
+ audio_midi_interface = standard.InterfaceDescriptor(
+ description="Midi goodness",
+ bInterfaceClass=audio.AUDIO_CLASS_DEVICE,
+ bInterfaceSubClass=audio.AUDIO_SUBCLASS_MIDI_STREAMING,
+ bInterfaceProtocol=audio.AUDIO_PROTOCOL_V1,
+ iInterface=StringIndex.index("{} MIDI".format(args.interface_name)),
+ subdescriptors=[
+ midi.Header(
+ jacks_and_elements=[
+ midi_in_jack_emb,
+ midi_in_jack_ext,
+ midi_out_jack_emb,
+ midi_out_jack_ext,
+ ],
+ ),
+ standard.EndpointDescriptor(
+ description="MIDI data out to {}".format(args.interface_name),
+ bEndpointAddress=args.midi_ep_num_out
+ | standard.EndpointDescriptor.DIRECTION_OUT,
+ bmAttributes=standard.EndpointDescriptor.TYPE_BULK,
+ bInterval=0,
+ wMaxPacketSize=512 if args.highspeed else 64,
+ ),
+ midi.DataEndpointDescriptor(baAssocJack=[midi_in_jack_emb]),
+ standard.EndpointDescriptor(
+ description="MIDI data in from {}".format(args.interface_name),
+ bEndpointAddress=args.midi_ep_num_in
+ | standard.EndpointDescriptor.DIRECTION_IN,
+ bmAttributes=standard.EndpointDescriptor.TYPE_BULK,
+ bInterval=0x0,
+ wMaxPacketSize=512 if args.highspeed else 64,
+ ),
+ midi.DataEndpointDescriptor(baAssocJack=[midi_out_jack_emb]),
+ ],
+ )
+
+ cs_ac_interface = audio10.AudioControlInterface(
description="Empty audio control",
- audio_streaming_interfaces = [],
- midi_streaming_interfaces = [
- audio_midi_interface
- ]
+ audio_streaming_interfaces=[],
+ midi_streaming_interfaces=[audio_midi_interface],
)
-audio_control_interface = standard.InterfaceDescriptor(
+ audio_control_interface = standard.InterfaceDescriptor(
description="All the audio",
bInterfaceClass=audio.AUDIO_CLASS_DEVICE,
bInterfaceSubClass=audio.AUDIO_SUBCLASS_CONTROL,
@@ -354,57 +462,89 @@ audio_control_interface = standard.InterfaceDescriptor(
iInterface=StringIndex.index("{} Audio".format(args.interface_name)),
subdescriptors=[
cs_ac_interface,
- ])
+ ],
+ )
-# Audio streaming interfaces must occur before MIDI ones.
-audio_interfaces = [audio_control_interface] + cs_ac_interface.audio_streaming_interfaces + cs_ac_interface.midi_streaming_interfaces
+ # Audio streaming interfaces must occur before MIDI ones.
+ audio_interfaces = (
+ [audio_control_interface]
+ + cs_ac_interface.audio_streaming_interfaces
+ + cs_ac_interface.midi_streaming_interfaces
+ )
interfaces_to_join = []
-if 'CDC' in args.devices:
+if include_cdc:
interfaces_to_join.append(cdc_interfaces)
-if 'MSC' in args.devices:
+if include_cdc2:
+ interfaces_to_join.append(cdc2_interfaces)
+
+if include_msc:
interfaces_to_join.append(msc_interfaces)
-if 'HID' in args.devices:
+if include_hid:
interfaces_to_join.append(hid_interfaces)
-if 'AUDIO' in args.devices:
+if include_audio:
interfaces_to_join.append(audio_interfaces)
# util.join_interfaces() will renumber the endpoints to make them unique across descriptors,
# and renumber the interfaces in order. But we still need to fix up certain
# interface cross-references.
-interfaces = util.join_interfaces(interfaces_to_join, renumber_endpoints=args.renumber_endpoints)
+interfaces = util.join_interfaces(
+ interfaces_to_join, renumber_endpoints=args.renumber_endpoints
+)
if args.max_ep != 0:
for interface in interfaces:
for subdescriptor in interface.subdescriptors:
- endpoint_address = getattr(subdescriptor, 'bEndpointAddress', 0) & 0x7f
+ endpoint_address = getattr(subdescriptor, "bEndpointAddress", 0) & 0x7F
if endpoint_address >= args.max_ep:
- raise ValueError("Endpoint address %d of %s must be less than %d" % (endpoint_address & 0x7f, interface.description, args.max_ep))
+ raise ValueError(
+ "Endpoint address %d of %s must be less than %d"
+ % (endpoint_address & 0x7F, interface.description, args.max_ep)
+ )
else:
- print("Unable to check whether maximum number of endpoints is respected", file=sys.stderr)
+ print(
+ "Unable to check whether maximum number of endpoints is respected",
+ file=sys.stderr,
+ )
# Now adjust the CDC interface cross-references.
-cdc_union.bMasterInterface = cdc_comm_interface.bInterfaceNumber
-cdc_union.bSlaveInterface_list = [cdc_data_interface.bInterfaceNumber]
+if include_cdc:
+ cdc_union.bMasterInterface = cdc_comm_interface.bInterfaceNumber
+ cdc_union.bSlaveInterface_list = [cdc_data_interface.bInterfaceNumber]
+
+ cdc_call_management.bDataInterface = cdc_data_interface.bInterfaceNumber
+
+if include_cdc2:
+ cdc2_union.bMasterInterface = cdc2_comm_interface.bInterfaceNumber
+ cdc2_union.bSlaveInterface_list = [cdc2_data_interface.bInterfaceNumber]
+
+ cdc2_call_management.bDataInterface = cdc2_data_interface.bInterfaceNumber
-cdc_call_management.bDataInterface = cdc_data_interface.bInterfaceNumber
-cdc_iad = standard.InterfaceAssociationDescriptor(
- description="CDC IAD",
- bFirstInterface=cdc_comm_interface.bInterfaceNumber,
- bInterfaceCount=len(cdc_interfaces),
- bFunctionClass=cdc.CDC_CLASS_COMM, # Communications Device Class
- bFunctionSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model
- bFunctionProtocol=cdc.CDC_PROTOCOL_NONE)
+def make_cdc_iad(cdc_comm_interface, name):
+ return standard.InterfaceAssociationDescriptor(
+ description="{} IAD".format(name),
+ bFirstInterface=cdc_comm_interface.bInterfaceNumber,
+ bInterfaceCount=len(cdc_interfaces),
+ bFunctionClass=cdc.CDC_CLASS_COMM, # Communications Device Class
+ bFunctionSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model
+ bFunctionProtocol=cdc.CDC_PROTOCOL_NONE,
+ )
+
+
+if include_cdc:
+ cdc_iad = make_cdc_iad(cdc_comm_interface, "CDC")
+if include_cdc2:
+ cdc2_iad = make_cdc_iad(cdc2_comm_interface, "CDC2")
descriptor_list = []
-if 'CDC' in args.devices:
+if include_cdc:
# Put the CDC IAD just before the CDC interfaces.
# There appears to be a bug in the Windows composite USB driver that requests the
# HID report descriptor with the wrong interface number if the HID interface is not given
@@ -414,13 +554,17 @@ if 'CDC' in args.devices:
descriptor_list.append(cdc_iad)
descriptor_list.extend(cdc_interfaces)
-if 'MSC' in args.devices:
+if include_cdc2:
+ descriptor_list.append(cdc2_iad)
+ descriptor_list.extend(cdc2_interfaces)
+
+if include_msc:
descriptor_list.extend(msc_interfaces)
-if 'HID' in args.devices:
+if include_hid:
descriptor_list.extend(hid_interfaces)
-if 'AUDIO' in args.devices:
+if include_audio:
# Only add the control interface because other audio interfaces are managed by it to ensure the
# correct ordering.
descriptor_list.append(audio_control_interface)
@@ -429,53 +573,74 @@ if 'AUDIO' in args.devices:
configuration = standard.ConfigurationDescriptor(
description="Composite configuration",
- wTotalLength=(standard.ConfigurationDescriptor.bLength +
- sum([len(bytes(x)) for x in descriptor_list])),
- bNumInterfaces=len(interfaces))
+ wTotalLength=(
+ standard.ConfigurationDescriptor.bLength
+ + sum([len(bytes(x)) for x in descriptor_list])
+ ),
+ bNumInterfaces=len(interfaces),
+)
descriptor_list.insert(0, configuration)
-string_descriptors = [standard.StringDescriptor(string) for string in StringIndex.strings_in_order()]
+string_descriptors = [
+ standard.StringDescriptor(string) for string in StringIndex.strings_in_order()
+]
serial_number_descriptor = string_descriptors[SERIAL_NUMBER_INDEX]
c_file = args.output_c_file
h_file = args.output_h_file
-c_file.write("""\
+c_file.write(
+ """\
#include <stdint.h>
#include "py/objtuple.h"
#include "shared-bindings/usb_hid/Device.h"
#include "{H_FILE_NAME}"
-""".format(H_FILE_NAME=h_file.name))
+""".format(
+ H_FILE_NAME=h_file.name
+ )
+)
-c_file.write("""\
+c_file.write(
+ """\
// {DESCRIPTION} : {CLASS}
-""".format(DESCRIPTION=device.description,
- CLASS=device.__class__))
+""".format(
+ DESCRIPTION=device.description, CLASS=device.__class__
+ )
+)
-c_file.write("""\
+c_file.write(
+ """\
const uint8_t usb_desc_dev[] = {
-""")
+"""
+)
for b in bytes(device):
c_file.write("0x{:02x}, ".format(b))
-c_file.write("""\
+c_file.write(
+ """\
};
-""")
+"""
+)
-c_file.write("""\
+c_file.write(
+ """\
const uint8_t usb_desc_cfg[] = {
-""")
+"""
+)
# Write out all the regular descriptors as one long array (that's how ASF4 does it).
descriptor_length = 0
for descriptor in descriptor_list:
- c_file.write("""\
+ c_file.write(
+ """\
// {DESCRIPTION} : {CLASS}
-""".format(DESCRIPTION=descriptor.description,
- CLASS=descriptor.__class__))
+""".format(
+ DESCRIPTION=descriptor.description, CLASS=descriptor.__class__
+ )
+ )
b = bytes(descriptor)
notes = descriptor.notes()
@@ -493,17 +658,22 @@ for descriptor in descriptor_list:
i += length
descriptor_length += len(b)
-c_file.write("""\
+c_file.write(
+ """\
};
-""")
+"""
+)
pointers_to_strings = []
for idx, descriptor in enumerate(string_descriptors):
- c_file.write("""\
+ c_file.write(
+ """\
// {DESCRIPTION} : {CLASS}
-""".format(DESCRIPTION=descriptor.description,
- CLASS=descriptor.__class__))
+""".format(
+ DESCRIPTION=descriptor.description, CLASS=descriptor.__class__
+ )
+ )
b = bytes(descriptor)
notes = descriptor.notes()
@@ -517,41 +687,56 @@ for idx, descriptor in enumerate(string_descriptors):
const = "const "
if variable_name == "usb_serial_number":
const = ""
- c_file.write("""\
+ c_file.write(
+ """\
{const}uint16_t {NAME}[] = {{
-""".format(const=const, NAME=variable_name))
+""".format(
+ const=const, NAME=variable_name
+ )
+ )
pointers_to_strings.append("{name}".format(name=variable_name))
n = 0
while i < len(b):
length = b[i]
for j in range(length // 2):
- c_file.write("0x{:04x}, ".format(b[i + 2*j + 1] << 8 | b[i + 2*j]))
+ c_file.write("0x{:04x}, ".format(b[i + 2 * j + 1] << 8 | b[i + 2 * j]))
n += 1
c_file.write("\n")
i += length
- c_file.write("""\
+ c_file.write(
+ """\
};
-""")
+"""
+ )
-c_file.write("""\
+c_file.write(
+ """\
// array of pointer to string descriptors
uint16_t const * const string_desc_arr [] =
{
-""")
-c_file.write(""",\
+"""
+)
+c_file.write(
+ """,\
-""".join(pointers_to_strings))
+""".join(
+ pointers_to_strings
+ )
+)
-c_file.write("""
+c_file.write(
+ """
};
-""")
+"""
+)
c_file.write("\n")
hid_descriptor_length = len(bytes(combined_hid_report_descriptor))
# Now we values we need for the .h file.
-h_file.write("""\
+h_file.write(
+ """\
#ifndef MICROPY_INCLUDED_AUTOGEN_USB_DESCRIPTOR_H
#define MICROPY_INCLUDED_AUTOGEN_USB_DESCRIPTOR_H
@@ -574,49 +759,78 @@ extern const uint8_t hid_report_descriptor[{hid_report_descriptor_length}];
// Product name included in Inquiry response, max 16 bytes
#define CFG_TUD_MSC_PRODUCT "{msc_product}"
-"""
-.format(serial_number_length=len(bytes(serial_number_descriptor)) // 2,
+""".format(
+ serial_number_length=len(bytes(serial_number_descriptor)) // 2,
device_length=len(bytes(device)),
configuration_length=descriptor_length,
max_configuration_length=max(hid_descriptor_length, descriptor_length),
string_descriptor_length=len(pointers_to_strings),
hid_report_descriptor_length=len(bytes(combined_hid_report_descriptor)),
- rhport0_mode='OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED' if args.highspeed else 'OPT_MODE_DEVICE',
+ rhport0_mode="OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED"
+ if args.highspeed
+ else "OPT_MODE_DEVICE",
hid_num_devices=len(args.hid_devices),
msc_vendor=args.manufacturer[:8],
- msc_product=args.product[:16]))
+ msc_product=args.product[:16],
+ )
+)
# Write out the report descriptor and info
-c_file.write("""\
+c_file.write(
+ """\
const uint8_t hid_report_descriptor[{HID_DESCRIPTOR_LENGTH}] = {{
-""".format(HID_DESCRIPTOR_LENGTH=hid_descriptor_length))
+""".format(
+ HID_DESCRIPTOR_LENGTH=hid_descriptor_length
+ )
+)
for b in bytes(combined_hid_report_descriptor):
c_file.write("0x{:02x}, ".format(b))
-c_file.write("""\
+c_file.write(
+ """\
};
-""")
+"""
+)
# Write out USB HID report buffer definitions.
for name in args.hid_devices:
- c_file.write("""\
+ c_file.write(
+ """\
static uint8_t {name}_report_buffer[{report_length}];
-""".format(name=name.lower(), report_length=hid_report_descriptors.HID_DEVICE_DATA[name].report_length))
+""".format(
+ name=name.lower(),
+ report_length=hid_report_descriptors.HID_DEVICE_DATA[name].report_length,
+ )
+ )
if hid_report_descriptors.HID_DEVICE_DATA[name].out_report_length > 0:
- c_file.write("""\
+ c_file.write(
+ """\
static uint8_t {name}_out_report_buffer[{report_length}];
-""".format(name=name.lower(), report_length=hid_report_descriptors.HID_DEVICE_DATA[name].out_report_length))
+""".format(
+ name=name.lower(),
+ report_length=hid_report_descriptors.HID_DEVICE_DATA[
+ name
+ ].out_report_length,
+ )
+ )
# Write out table of device objects.
-c_file.write("""
+c_file.write(
+ """
usb_hid_device_obj_t usb_hid_devices[] = {
-""")
+"""
+)
for name in args.hid_devices:
device_data = hid_report_descriptors.HID_DEVICE_DATA[name]
- out_report_buffer = '{}_out_report_buffer'.format(name.lower()) if device_data.out_report_length > 0 else 'NULL'
- c_file.write("""\
+ out_report_buffer = (
+ "{}_out_report_buffer".format(name.lower())
+ if device_data.out_report_length > 0
+ else "NULL"
+ )
+ c_file.write(
+ """\
{{
.base = {{ .type = &usb_hid_device_type }},
.report_buffer = {name}_report_buffer,
@@ -627,34 +841,52 @@ for name in args.hid_devices:
.out_report_buffer = {out_report_buffer},
.out_report_length = {out_report_length},
}},
-""".format(name=name.lower(), report_id=report_ids[name],
- report_length=device_data.report_length,
- usage_page=device_data.usage_page,
- usage=device_data.usage,
- out_report_buffer=out_report_buffer,
- out_report_length=device_data.out_report_length))
-c_file.write("""\
+""".format(
+ name=name.lower(),
+ report_id=report_ids[name],
+ report_length=device_data.report_length,
+ usage_page=device_data.usage_page,
+ usage=device_data.usage,
+ out_report_buffer=out_report_buffer,
+ out_report_length=device_data.out_report_length,
+ )
+ )
+c_file.write(
+ """\
};
-""")
+"""
+)
# Write out tuple of device objects.
-c_file.write("""
+c_file.write(
+ """
mp_obj_tuple_t common_hal_usb_hid_devices = {{
.base = {{
.type = &mp_type_tuple,
}},
.len = {num_devices},
.items = {{
-""".format(num_devices=len(args.hid_devices)))
+""".format(
+ num_devices=len(args.hid_devices)
+ )
+)
for idx in range(len(args.hid_devices)):
- c_file.write("""\
+ c_file.write(
+ """\
(mp_obj_t) &usb_hid_devices[{idx}],
-""".format(idx=idx))
-c_file.write("""\
+""".format(
+ idx=idx
+ )
+ )
+c_file.write(
+ """\
},
};
-""")
+"""
+)
-h_file.write("""\
+h_file.write(
+ """\
#endif // MICROPY_INCLUDED_AUTOGEN_USB_DESCRIPTOR_H
-""")
+"""
+)
diff --git a/tools/usb_descriptor b/tools/usb_descriptor
-Subproject 701cafc50e2e574dccaf7a340eedbd64a0b41a4
+Subproject 2eaa6114b209fe7f0a795eda8d6a7b3b93d76d2