summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorHiFiPHile <[email protected]>2026-08-25 09:27:48 +0200
committerHiFiPHile <[email protected]>2026-08-25 09:27:48 +0200
commitdfac26a272fa7bbbca2050fbe9f1ca09008e548e (patch)
treeefbc53f8f2c1e5d9c7f38e5fef6d774a20053cec /tools
parente590b45fcf51f9ddace73178074e4fe6d691e319 (diff)
parent5c0e31cdabaf37f14e1f5e988a020abfc1000495 (diff)
Merge master updates into the UAC1 host branch
Bring the audio work onto the current host core and build files before applying the remaining review fixes. Signed-off-by: HiFiPHile <[email protected]>
Diffstat (limited to 'tools')
-rw-r--r--tools/88-tinyusb.rules93
-rwxr-xr-xtools/build.py1
-rw-r--r--tools/check_example_pids.py55
-rw-r--r--tools/codespell/ignore-words.txt1
-rwxr-xr-xtools/get_deps.py9
-rw-r--r--tools/metrics_compare_base.py4
-rw-r--r--tools/usb_drivers/tinyusb_win_usbser.inf4
7 files changed, 163 insertions, 4 deletions
diff --git a/tools/88-tinyusb.rules b/tools/88-tinyusb.rules
new file mode 100644
index 000000000..e0c5215b0
--- /dev/null
+++ b/tools/88-tinyusb.rules
@@ -0,0 +1,93 @@
+# Copy this file to the location of your distribution's udev rules:
+# Then reload udev configuration by executing:
+# sudo cp 88-tinyusb.rules /etc/udev/rules.d/ && sudo udevadm control --reload-rules && sudo udevadm trigger
+
+# Check SUBSYSTEM
+SUBSYSTEMS=="hidraw", KERNEL=="hidraw*", MODE="0666", GROUP="dialout"
+SUBSYSTEM=="usbmon", MODE="0640", GROUP="wireshark"
+
+# Rule applies to all TinyUSB example
+ATTRS{idVendor}=="cafe", MODE="0666", GROUP="dialout"
+
+# Rule to make Trinket/Pro Trinket/Gemma/Flora programmable without running Arduino as root.
+# Tested with Ubuntu 14.04 and 12.04. Other distributions might need to update GROUP="dialout"
+# to another group value like "users".
+SUBSYSTEM=="usb", ATTRS{idProduct}=="0c9f", ATTRS{idVendor}=="1781", MODE="0660", GROUP="dialout"
+
+# Rule to blacklist Adafruit USB CDC boards from being manipulated by ModemManager.
+# Fixes issue with hanging references to /dev/ttyACM* devices on Ubuntu 15.04.
+ATTRS{idVendor}=="239a", ENV{ID_MM_DEVICE_IGNORE}="1"
+
+# All Adafruit boards
+ATTRS{idVendor}=="239a", MODE="0660", GROUP="adm"
+
+# All Espressif boards
+ATTRS{idVendor}=="303a", MODE="0660", GROUP="adm"
+
+# All RaspberryPi boards
+ATTRS{idVendor}=="2e8a", MODE="0660", GROUP="adm"
+
+# All NXP Boards
+ATTRS{idVendor}=="1fc9", MODE="0660", GROUP="adm"
+
+# All ST
+SUBSYSTEM=="usb", ATTRS{idVendor}=="0483", GROUP="adm"
+
+# Rule to blacklist TinyUSB example from being manipulated by ModemManager.
+SUBSYSTEMS=="usb", ATTRS{idVendor}=="cafe", ENV{ID_MM_DEVICE_IGNORE}="1"
+
+# Xplained Pro SamG55 Device
+SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2111", MODE="0666", GROUP="users", ENV{ID_MM_DEVICE_IGNORE}="1"
+SUBSYSTEMS=="tty", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2111", MODE="0666", GROUP="users", ENV{ID_MM_DEVICE_IGNORE}="1"
+
+# TI Stellaris/Tiva-C Launchpad ICDI
+SUBSYSTEM=="usb", ATTRS{idVendor}=="1cbe", ATTRS{idProduct}=="00fd", MODE="0666"
+
+# CMSIS-DAP, vendor = ARM
+SUBSYSTEM=="usb", ATTR{idVendor}=="0d28", MODE="0666"
+
+# wch-link
+SUBSYSTEM=="usb", ATTR{idVendor}=="1a86", ATTR{idProduct}=="8010", GROUP="plugdev"
+SUBSYSTEM=="usb", ATTR{idVendor}=="4348", ATTR{idProduct}=="55e0", GROUP="plugdev"
+SUBSYSTEM=="usb", ATTR{idVendor}=="1a86", ATTR{idProduct}=="8012", GROUP="plugdev"
+
+# Pxlogic
+SUBSYSTEM=="usb", ATTRS{idVendor}=="2a0e", MODE="0666"
+SUBSYSTEM=="usb", ATTRS{idVendor}=="1a86", MODE="0666"
+
+# Arduino Renesas
+SUBSYSTEMS=="usb", ATTRS{idVendor}=="2341", MODE="0666"
+
+# E2/E2 Lite/E1/E20/IE850A emulator
+ATTR{idProduct}=="82a1", ATTR{idVendor}=="045b", MODE="0666"
+ATTR{idProduct}=="82a0", ATTR{idVendor}=="045b", MODE="0666"
+ATTR{idProduct}=="823b", ATTR{idVendor}=="045b", MODE="0666"
+ATTR{idProduct}=="823c", ATTR{idVendor}=="045b", MODE="0666"
+ATTR{idProduct}=="0250", ATTR{idVendor}=="045b", MODE="0666"
+# Prevent E2/E2Lite/E1/E20/IE850A from being captured by modem manager service as E2/E2 Lite/E1/E20/IE850A is not a modem
+ATTR{idProduct}=="82a1", ATTR{idVendor}=="045b", ENV{ID_MM_DEVICE_IGNORE}="1"
+ATTR{idProduct}=="82a0", ATTR{idVendor}=="045b", ENV{ID_MM_DEVICE_IGNORE}="1"
+ATTR{idProduct}=="823b", ATTR{idVendor}=="045b", ENV{ID_MM_DEVICE_IGNORE}="1"
+ATTR{idProduct}=="823c", ATTR{idVendor}=="045b", ENV{ID_MM_DEVICE_IGNORE}="1"
+ATTR{idProduct}=="0250", ATTR{idVendor}=="045b", ENV{ID_MM_DEVICE_IGNORE}="1"
+
+#TI MSP430UIF
+ATTRS{idVendor}=="2047",ATTRS{idProduct}=="0010",MODE="0666"
+ATTRS{idVendor}=="2047",ATTRS{idProduct}=="0013",MODE="0666"
+ATTRS{idVendor}=="2047",ATTRS{idProduct}=="0014",MODE="0666"
+ATTRS{idVendor}=="2047",ATTRS{idProduct}=="0203",MODE="0666"
+ATTRS{idVendor}=="2047",ATTRS{idProduct}=="0204",MODE="0666"
+ATTRS{idVendor}=="0451",ATTRS{idProduct}=="f432",MODE="0666"
+
+# fomu
+ATTRS{idVendor}=="1209",ATTRS{idProduct}=="5bf0",MODE="0666"
+
+# FTDI
+ATTRS{idVendor}=="0403", MODE="0660", GROUP="adm"
+
+# Sipeed Slogic16
+SUBSYSTEM=="usb", ATTRS{idVendor}=="359f", MODE="0666", TAG+="uaccess", ENV{ID_MM_DEVICE_IGNORE}="1"
+
+# ataradov usb-sniffer (github.com/ataradov/usb-sniffer): programmed unit + blank FX2LP
+ATTRS{idVendor}=="6666", ATTRS{idProduct}=="6620", MODE="0666"
+ATTRS{idVendor}=="04b4", ATTRS{idProduct}=="8613", MODE="0666"
diff --git a/tools/build.py b/tools/build.py
index 5eaaeb513..51d3d0f70 100755
--- a/tools/build.py
+++ b/tools/build.py
@@ -92,6 +92,7 @@ def get_examples(family):
if family == 'espressif':
all_examples.append('device/board_test')
+ all_examples.append('device/usbtest')
all_examples.append('device/video_capture')
all_examples.append('host/device_info')
all_examples.sort()
diff --git a/tools/check_example_pids.py b/tools/check_example_pids.py
new file mode 100644
index 000000000..d8795af34
--- /dev/null
+++ b/tools/check_example_pids.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python3
+"""Check that every example enumerates with a unique USB PID.
+
+Each example's usb_descriptors.c hardcodes its idProduct (0x40xx). Uniqueness is what
+guarantees back-to-back re-enumeration on the HIL rig and a fresh host driver match, and
+it is easy to break by hand: a new example copying a neighbour's PID, or an arithmetic
+PID (dynamic_configuration derives a second one from USB_PID). This collects every
+`#define USB_PID 0x....`, every literal `.idProduct = 0x....`, and every `USB_PID + <n>`
+derivation across examples/, and fails on any duplicate value.
+"""
+
+import re
+import sys
+from pathlib import Path
+
+EXAMPLES = Path(__file__).resolve().parents[1] / 'examples'
+
+RE_DEFINE = re.compile(r'#define\s+USB_PID\s+\(?(0x[0-9a-fA-F]+)\)?')
+RE_LITERAL = re.compile(r'\.idProduct\s*=\s*(0x[0-9a-fA-F]+)')
+RE_DERIVED = re.compile(r'\.idProduct\s*=\s*USB_PID\s*\+\s*(0x[0-9a-fA-F]+|\d+)')
+
+
+def main() -> int:
+ pids: dict[int, list[str]] = {}
+ for f in sorted(EXAMPLES.glob('*/*/src/usb_descriptors.c')):
+ text = f.read_text(errors='replace')
+ rel = f.relative_to(EXAMPLES.parent)
+ base = None
+ m = RE_DEFINE.search(text)
+ if m:
+ base = int(m.group(1), 16)
+ for m in RE_LITERAL.finditer(text):
+ pids.setdefault(int(m.group(1), 16), []).append(str(rel))
+ for m in RE_DERIVED.finditer(text):
+ if base is None:
+ print(f'{rel}: derived idProduct but no USB_PID define', file=sys.stderr)
+ return 1
+ pids.setdefault(base + int(m.group(1), 0), []).append(f'{rel} (USB_PID + {m.group(1)})')
+ # examples whose descriptor uses .idProduct = USB_PID pick up the define itself
+ if base is not None and re.search(r'\.idProduct\s*=\s*USB_PID\s*[,;]', text):
+ pids.setdefault(base, []).append(str(rel))
+
+ dups = {pid: users for pid, users in pids.items() if len(users) > 1}
+ for pid, users in sorted(dups.items()):
+ print(f'duplicate USB PID 0x{pid:04x}:', file=sys.stderr)
+ for u in users:
+ print(f' {u}', file=sys.stderr)
+ if dups:
+ return 1
+ print(f'{len(pids)} unique example USB PIDs')
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/tools/codespell/ignore-words.txt b/tools/codespell/ignore-words.txt
index 0b1aa284a..6b301d27b 100644
--- a/tools/codespell/ignore-words.txt
+++ b/tools/codespell/ignore-words.txt
@@ -5,6 +5,7 @@ endianess
fro
hsi
inout
+linke
mot
ore
pris
diff --git a/tools/get_deps.py b/tools/get_deps.py
index 9d745ee26..baaf3761f 100755
--- a/tools/get_deps.py
+++ b/tools/get_deps.py
@@ -46,6 +46,9 @@ deps_optional = {
'hw/mcu/gd/nuclei-sdk': ['https://github.com/Nuclei-Software/nuclei-sdk.git',
'7eb7bfa9ea4fbeacfafe1d5f77d5a0e6ed3922e7',
'gd32vf103'],
+ 'hw/mcu/geehy/APM32F0xx_SDK': ['https://github.com/GeehySemi/APM32F0xx_SDK.git',
+ 'cfc1fe826e1869133de86d4c6b298fc153e6bc32',
+ 'apm32f0xx'],
'hw/mcu/infineon/mtb-xmclib-cat3': ['https://github.com/Infineon/mtb-xmclib-cat3.git',
'daf5500d03cba23e68c2f241c30af79cd9d63880',
'xmc4000'],
@@ -82,6 +85,12 @@ deps_optional = {
'hw/mcu/nxp/mcux-devices-rt': ['https://github.com/nxp-mcuxpresso/mcux-devices-rt',
'dba2b523c9df61f3330bd186242f8210a8e47c45',
'imxrt'],
+ 'hw/mcu/puya/PY32F071_Firmware': ['https://github.com/OpenPuya/PY32F071_Firmware.git',
+ '73e384cddce63e3019de41d9b6af17dfc96fa536',
+ 'py32f0'],
+ 'hw/mcu/puya/PY32F072_Firmware': ['https://github.com/OpenPuya/PY32F072_Firmware.git',
+ 'bc3a6cdbece335a27abb8b51e6fc4911f5116185',
+ 'py32f0'],
'hw/mcu/raspberry_pi/FreeRTOS-Kernel': ['https://github.com/raspberrypi/FreeRTOS-Kernel.git',
'4f7299d6ea746b27a9dd19e87af568e34bd65b15',
'rp2040'],
diff --git a/tools/metrics_compare_base.py b/tools/metrics_compare_base.py
index 799a96800..844130097 100644
--- a/tools/metrics_compare_base.py
+++ b/tools/metrics_compare_base.py
@@ -81,7 +81,7 @@ def symlink_deps(main_root, worktree_dir):
def ci_first_boards():
"""Return the first board (alphabetical) of each arm-gcc CI family."""
- matrix_py = os.path.join(TINYUSB_ROOT, '.github', 'workflows', 'ci_set_matrix.py')
+ matrix_py = os.path.join(TINYUSB_ROOT, '.github', 'scripts', 'ci_set_matrix.py')
if not os.path.isfile(matrix_py):
return []
ret = run([sys.executable, matrix_py])
@@ -188,7 +188,7 @@ def main():
args.combined = True
ci_boards = ci_first_boards()
if not ci_boards:
- parser.error('--ci: failed to derive boards from .github/workflows/ci_set_matrix.py')
+ parser.error('--ci: failed to derive boards from .github/scripts/ci_set_matrix.py')
# Append, dedup, preserve order
seen = set(args.board)
for b in ci_boards:
diff --git a/tools/usb_drivers/tinyusb_win_usbser.inf b/tools/usb_drivers/tinyusb_win_usbser.inf
index 659f048ae..e3875a478 100644
--- a/tools/usb_drivers/tinyusb_win_usbser.inf
+++ b/tools/usb_drivers/tinyusb_win_usbser.inf
@@ -88,11 +88,11 @@ ServiceBinary=%12%\%DRIVERFILENAME%.sys
[SourceDisksNames]
[DeviceList]
-%DESCRIPTION%=DriverInstall, USB\VID_CAFE&PID_4001&MI_00, USB\VID_CAFE&PID_4003&MI_00, USB\VID_CAFE&PID_4005&MI_00, USB\VID_CAFE&PID_4007&MI_00, USB\VID_CAFE&PID_4009&MI_00, USB\VID_CAFE&PID_400b&MI_00, USB\VID_CAFE&PID_400d&MI_00, USB\VID_CAFE&PID_400f&MI_00, USB\VID_CAFE&PID_4011&MI_00, USB\VID_CAFE&PID_4013&MI_00, USB\VID_CAFE&PID_4015&MI_00, USB\VID_CAFE&PID_4017&MI_00, USB\VID_CAFE&PID_4019&MI_00, USB\VID_CAFE&PID_401b&MI_00, USB\VID_CAFE&PID_401d&MI_00, USB\VID_CAFE&PID_401f&MI_00, USB\VID_CAFE&PID_4021&MI_00, USB\VID_CAFE&PID_4023&MI_00, USB\VID_CAFE&PID_4025&MI_00, USB\VID_CAFE&PID_4027&MI_00, USB\VID_CAFE&PID_4029&MI_00, USB\VID_CAFE&PID_402b&MI_00, USB\VID_CAFE&PID_402d&MI_00, USB\VID_CAFE&PID_402f&MI_00, USB\VID_CAFE&PID_4031&MI_00, USB\VID_CAFE&PID_4033&MI_00, USB\VID_CAFE&PID_4035&MI_00, USB\VID_CAFE&PID_4037&MI_00, USB\VID_CAFE&PID_4039&MI_00, USB\VID_CAFE&PID_403b&MI_00, USB\VID_CAFE&PID_403d&MI_00, USB\VID_CAFE&PID_403f&MI_00
+%DESCRIPTION%=DriverInstall, USB\VID_CAFE&PID_4001&MI_00, USB\VID_CAFE&PID_4003&MI_00, USB\VID_CAFE&PID_4005&MI_00, USB\VID_CAFE&PID_4007&MI_00, USB\VID_CAFE&PID_4009&MI_00, USB\VID_CAFE&PID_400b&MI_00, USB\VID_CAFE&PID_400d&MI_00, USB\VID_CAFE&PID_400f&MI_00, USB\VID_CAFE&PID_4011&MI_00, USB\VID_CAFE&PID_4013&MI_00, USB\VID_CAFE&PID_4015&MI_00, USB\VID_CAFE&PID_4017&MI_00, USB\VID_CAFE&PID_4019&MI_00, USB\VID_CAFE&PID_401b&MI_00, USB\VID_CAFE&PID_401d&MI_00, USB\VID_CAFE&PID_401f&MI_00, USB\VID_CAFE&PID_4021&MI_00, USB\VID_CAFE&PID_4023&MI_00, USB\VID_CAFE&PID_4025&MI_00, USB\VID_CAFE&PID_4027&MI_00, USB\VID_CAFE&PID_4029&MI_00, USB\VID_CAFE&PID_402b&MI_00, USB\VID_CAFE&PID_402d&MI_00, USB\VID_CAFE&PID_402f&MI_00, USB\VID_CAFE&PID_4031&MI_00, USB\VID_CAFE&PID_4033&MI_00, USB\VID_CAFE&PID_4035&MI_00, USB\VID_CAFE&PID_4037&MI_00, USB\VID_CAFE&PID_4039&MI_00, USB\VID_CAFE&PID_403b&MI_00, USB\VID_CAFE&PID_403d&MI_00, USB\VID_CAFE&PID_403f&MI_00, USB\VID_CAFE&PID_4006&MI_00, USB\VID_CAFE&PID_4008&MI_00, USB\VID_CAFE&PID_400a&MI_00, USB\VID_CAFE&PID_4020&MI_00, USB\VID_CAFE&PID_4022&MI_00
[DeviceList.NTamd64]
-%DESCRIPTION%=DriverInstall, USB\VID_CAFE&PID_4001&MI_00, USB\VID_CAFE&PID_4003&MI_00, USB\VID_CAFE&PID_4005&MI_00, USB\VID_CAFE&PID_4007&MI_00, USB\VID_CAFE&PID_4009&MI_00, USB\VID_CAFE&PID_400b&MI_00, USB\VID_CAFE&PID_400d&MI_00, USB\VID_CAFE&PID_400f&MI_00, USB\VID_CAFE&PID_4011&MI_00, USB\VID_CAFE&PID_4013&MI_00, USB\VID_CAFE&PID_4015&MI_00, USB\VID_CAFE&PID_4017&MI_00, USB\VID_CAFE&PID_4019&MI_00, USB\VID_CAFE&PID_401b&MI_00, USB\VID_CAFE&PID_401d&MI_00, USB\VID_CAFE&PID_401f&MI_00, USB\VID_CAFE&PID_4021&MI_00, USB\VID_CAFE&PID_4023&MI_00, USB\VID_CAFE&PID_4025&MI_00, USB\VID_CAFE&PID_4027&MI_00, USB\VID_CAFE&PID_4029&MI_00, USB\VID_CAFE&PID_402b&MI_00, USB\VID_CAFE&PID_402d&MI_00, USB\VID_CAFE&PID_402f&MI_00, USB\VID_CAFE&PID_4031&MI_00, USB\VID_CAFE&PID_4033&MI_00, USB\VID_CAFE&PID_4035&MI_00, USB\VID_CAFE&PID_4037&MI_00, USB\VID_CAFE&PID_4039&MI_00, USB\VID_CAFE&PID_403b&MI_00, USB\VID_CAFE&PID_403d&MI_00, USB\VID_CAFE&PID_403f&MI_00
+%DESCRIPTION%=DriverInstall, USB\VID_CAFE&PID_4001&MI_00, USB\VID_CAFE&PID_4003&MI_00, USB\VID_CAFE&PID_4005&MI_00, USB\VID_CAFE&PID_4007&MI_00, USB\VID_CAFE&PID_4009&MI_00, USB\VID_CAFE&PID_400b&MI_00, USB\VID_CAFE&PID_400d&MI_00, USB\VID_CAFE&PID_400f&MI_00, USB\VID_CAFE&PID_4011&MI_00, USB\VID_CAFE&PID_4013&MI_00, USB\VID_CAFE&PID_4015&MI_00, USB\VID_CAFE&PID_4017&MI_00, USB\VID_CAFE&PID_4019&MI_00, USB\VID_CAFE&PID_401b&MI_00, USB\VID_CAFE&PID_401d&MI_00, USB\VID_CAFE&PID_401f&MI_00, USB\VID_CAFE&PID_4021&MI_00, USB\VID_CAFE&PID_4023&MI_00, USB\VID_CAFE&PID_4025&MI_00, USB\VID_CAFE&PID_4027&MI_00, USB\VID_CAFE&PID_4029&MI_00, USB\VID_CAFE&PID_402b&MI_00, USB\VID_CAFE&PID_402d&MI_00, USB\VID_CAFE&PID_402f&MI_00, USB\VID_CAFE&PID_4031&MI_00, USB\VID_CAFE&PID_4033&MI_00, USB\VID_CAFE&PID_4035&MI_00, USB\VID_CAFE&PID_4037&MI_00, USB\VID_CAFE&PID_4039&MI_00, USB\VID_CAFE&PID_403b&MI_00, USB\VID_CAFE&PID_403d&MI_00, USB\VID_CAFE&PID_403f&MI_00, USB\VID_CAFE&PID_4006&MI_00, USB\VID_CAFE&PID_4008&MI_00, USB\VID_CAFE&PID_400a&MI_00, USB\VID_CAFE&PID_4020&MI_00, USB\VID_CAFE&PID_4022&MI_00
;------------------------------------------------------------------------------
; String Definitions