vendors: ingest upstream PID allocation registries + Arduino-core boards.txt (vendors branch sync) · Issue #43 · FastLED/boards · GitHub
Skip to content

vendors: ingest upstream PID allocation registries + Arduino-core boards.txt (vendors branch sync) #43

Open

Description

@zackees

Goal

Populate the vendors orphan branch with upstream-curated vendor PID allocation registries — the tier-1+2 sources fbuild's online-data aggregator (v1) was designed to ingest, but never did because the curation pipeline outgrew "a few scripts in one workflow." Per design.md, fastled/boards is the v2 home for this data.

Today: vendors carries only README.md + _meta.json (placeholder). No sync-vendors.yml workflow exists on main. No tools/sync_vendors.py exists.

The full upstream source catalog has already been triaged at FastLED/fbuild#722 with 17 per-vendor sub-issues. Since the architecture moved here, the ingestion belongs here — fbuild should consume the resulting vendors branch data, not re-do the upstream fetches.

Upstream sources to ingest

Tier 1 — authoritative PID allocation registries (gold standard)

Vendor VID Upstream Format
Raspberry Pi Foundation 0x2E8A raspberrypi/usb-pid → Readme.md Markdown table (Pico, Pimoroni, Cytron, WIZnet, TI USB-TMC …)
Espressif Systems 0x303A espressif/usb-pids → allocated-pids.txt + allocated-pids-espressif-devboards.txt Plain text VVVV:PPPP description (TinyS2, LILYGO, ATMegaZero, ESP32-S3-DevKitC, ESP32-P4 …)

These are the most precise sources — per-board PID resolution, not per-vendor.

Tier 2 — Arduino-core boards.txt (per-board manifests)

Vendor VID(s) Upstream Notes
Arduino (AVR) 0x2341, 0x2A03 arduino/ArduinoCore-avr → boards.txt Leonardo, Micro, Esplora, Yún
Arduino (SAMD) 0x03EB, 0x2341 arduino/ArduinoCore-samd → boards.txt Zero, MKR family, Nano 33 IoT
Arduino-ESP32 0x303A, partner VIDs espressif/arduino-esp32 → boards.txt ESP32-S2/S3/C3 + UM TinyS2, LOLIN S2 Mini
Adafruit 0x239A adafruit/Adafruit_nRF52_Arduino → boards.txt Feather, ItsyBitsy, CPB, CLUE
Silicon Labs 0x2341, 0x2886 SiliconLabs/arduino → boards.txt Nano Matter, XIAO MG24
STM32 (community) 0x0483 stm32duino/Arduino_Core_STM32 → boards.txt Nucleo, Discovery, Eval, generic STM32
Teensy 0x16C0 PJRC teensy_loader source Teensy 3.x/4.x/LC

Tier 3-4 — community / archived / single-pair

Vendor VID Upstream Notes
Nordic Semiconductor 0x1915 NordicSemiconductor/nrf-udev → 71-nrf.rules Vendor-level only
Nordic (pca10059 explicit) 0x1915 / 0x521F NordicSemiconductor/nrf-device-setup-js (archived 2022-01) Single explicit pair

Known gaps (no public registry — flag in _meta.json provenance)

  • NXP (MCUXpresso): per-example USB descriptors only, no centralized registry.
  • Microchip (Harmony USB): same shape.
  • TI: no maintained list (energia/Energia unmaintained).
  • STM32 official: ST does not publish; stm32duino is community-run.

See fbuild#722 for the full per-vendor breakdown of which sub-issue covers which source.

Proposed implementation

  1. tools/sync_vendors.py (on main) — fetcher + parser per source, modeled on the existing tools/sync_*.py pattern. Each source produces a vendors/<vendor>.json with the shape:
    {
      "vid": "0x303A",
      "vendor_name": "Espressif Systems",
      "source_url": "https://github.com/espressif/usb-pids",
      "source_sha": "<commit hash>",
      "fetched_at": "2026-MM-DDTHH:MM:SSZ",
      "license": "<from source repo>",
      "boards": [
        {"pid": "0x1001", "name": "ESP32-S2 Saola"},
        {"pid": "0x4002", "name": "Unexpected Maker TinyS2"},
        ...
      ]
    }
  2. .github/workflows/sync-vendors.yml (on main) — nightly cron + workflow_dispatch, runs tools/sync_vendors.py, then publishes the output to the vendors orphan branch via tools/git_publish.py (force-with-lease, history pruned to ~200 commits — same machinery as the other orphan-branch workflows).
  3. _meta.json on the vendors branch — provenance record per source: URL, commit SHA, fetch timestamp, license, parse status. Known-gap vendors (NXP/Microchip/TI) listed with explanation so consumers know the data is intentionally absent.
  4. build_usb_ids.py (already on main) — extend to fold vendors/*.json into the aggregate so the site branch's SQLite carries per-board PID resolution.

Acceptance criteria

  • tools/sync_vendors.py parses all 7 Arduino-core sources + 2 tier-1 PID registries + Nordic udev rules.
  • .github/workflows/sync-vendors.yml runs nightly + on workflow_dispatch, publishes to vendors branch.
  • vendors/_meta.json lists every source with its commit SHA + fetch timestamp; known-gap vendors documented.
  • First successful run carries at least 200 per-board entries across all sources.
  • build_usb_ids.py ingests the per-board data; the site branch's SQLite vidpid table returns "Pico CircuitPython" for 2e8a000b (not just "Pico SDK CDC UART").
  • fbuild's #722 acceptance criterion ("fbuild-core::usb::resolver::pretty(0x303A, 0x4002) returns 'Unexpected Maker TinyS2 Arduino'") passes once fbuild consumes from this branch instead of doing its own fetches.

Why this belongs here (not fbuild)

  • Per design.md: the curation pipeline outgrew fbuild's online-data v1 — the explicit purpose of this repo is to be the v2 aggregator.
  • The vendors orphan branch is already set up and waiting for data.
  • Other consumers (the public boards portal at the site branch) need the same data and can read directly from this repo without depending on fbuild.
  • Single source of truth for VID:PID across the fastled organization.

Downstream coordination

Once this lands, FastLED/fbuild#722 closes — fbuild's online-data consumer simply reads vendors/*.json from this repo instead of re-fetching from the same upstream sources. The 17 per-vendor sub-issues (#723–#739) become trivially-done from fbuild's side because the data lives here.

Activity

  1. zackees commented on Jun 30, 2026

    @zackees
    MemberAuthor

    Status update — 2026-06-29 exhaustive source catalog

    A 4-agent parallel sweep across (a) vendor PID registries, (b) Arduino-core boards.txt ecosystem, (c) bootloader/flashing-tool sources, and (d) system-level USB databases catalogued every known VID/PID data store. The full list below replaces and supersedes the smaller table from the original issue body.


    TIER 1 — Official vendor PID allocation registries (gold standard)

    Source VID Format Coverage License
    raspberrypi/usb-pid 0x2E8A Markdown table ~250 Pico/Pimoroni/Cytron/WIZnet/TI USB-TMC TBD
    espressif/usb-pids 0x303A Plain text VVVV:PPPP description ~400 Espressif chips + customer devboards TBD
    pidcodes/pidcodes.github.com 0x1209 Per-PID Markdown files (YAML frontmatter) ~600 open-hardware projects TBD
    openmoko/openmoko-usb-oui 0x1D50 PSV (usb_product_ids.psv) ~250 (Ubertooth, Rockbox, open-hw) TBD
    obdev/v-usb + VOTI 0x16C0 Plain text rules + HTML ~100 sub-allocations by USB class GPLv2
    creationid/creators N/A (32-bit creation ID) Per-creator Markdown ~50 CircuitPython non-USB boards TBD

    Found NEGATIVE for official registries: STMicroelectronics, NXP, Microchip/Atmel, Nordic, Silicon Labs, Texas Instruments, Renesas, Cypress/Infineon, Ambiq, WCH/openwch, DFRobot, Pimoroni. These vendors either reuse SDK-default PIDs across all boards or assign customer PIDs privately by email. Their per-board PIDs are only recoverable via tier-2 board-manifest sources.


    TIER 2 — Board-manifest sources (per-board USB hwids embedded in board defs)

    PlatformIO + already cataloged

    Source VID(s) Coverage
    PlatformIO board registry + per-platform repos all ~1500+ boards across all PIO platforms — hwids array
    arduino/ArduinoCore-avr 0x2341 Leonardo, Micro, Esplora, Yún
    arduino/ArduinoCore-samd 0x03EB, 0x2341 Zero, MKR family, Nano 33 IoT
    espressif/arduino-esp32 0x303A + partner VIDs ESP32-S2/S3/C3 + UM TinyS2, LOLIN
    adafruit/Adafruit_nRF52_Arduino 0x239A Feather, ItsyBitsy, CPB, CLUE
    SiliconLabs/arduino 0x2341, 0x2886 Nano Matter, XIAO MG24
    stm32duino/Arduino_Core_STM32 0x0483 Nucleo, Discovery, Eval, generic STM32

    Arduino-core ecosystem (NEW — not yet in #43)

    Source VID(s) Coverage
    arduino/ArduinoCore-mbed 0x2341, 0x2e8a, 0x35d1 Portenta H7/X8, Nano 33 BLE, Nano RP2040 Connect, Nicla, Opta, Giga R1, Stella, Edge Control
    arduino/ArduinoCore-renesas 0x2341 UNO R4 Minima/WiFi, Nano R4, Portenta C33, Opta Digital/Analog, Science Kit R3
    arduino/ArduinoCore-megaavr 0x03eb, 0x2341 UNO WiFi Rev2, Nano Every
    arduino/ArduinoCore-sam 0x2341, 0x2A03 Arduino Due (programming + native USB)
    arduino/ArduinoCore-zephyr 0x1fc9, 0x2341 Giga, Nano 33 BLE, Portenta, Nicla, Opta, EK-RA8D1, FRDM-MCXN947/RW612
    earlephilhower/arduino-pico 0x1209, 0x15ba, 0x1b4f, 0x1d50, 0x2341, 0x239a, 0x2770, 0x2886, 0x2e8a, 0x2e8b, 0x3343 147 boards across 11 VIDs — largest community RP2040/RP2350 core
    adafruit/ArduinoCore-samd 0x239A 36 boards (Feather M0/M4, Metro, ItsyBitsy, Trinket, Gemma, QT Py, Grand Central, Hallowing, PyBadge)
    sparkfun/Arduino_Boards (avr+samd) 0x1B4F 25 boards (Pro Micro, Fio v3, MaKey MaKey, LilyPad USB+, RedBot, SAMD21 Dev/Mini/Pro RF, 9DoF Razor IMU M0, RedBoard Turbo, SAMD51 Thing Plus/MicroMod, LoRaSerial)
    Seeed-Studio/ArduinoCore-samd 0x2886 10 boards (XIAO M0, Wio Terminal, Seeeduino XIAO/Lotus, Femto M0)
    Seeed-Studio/Adafruit_nRF52_Arduino 0x2886 6 boards (XIAO nRF52840 + Sense/Plus variants)
    Seeed-Studio/ArduinoCore-mbed 0x2886 XIAO nRF52840-Sense mbed
    Seeed-Studio/ArduinoCore-renesas 0x2341 6 Seeed Renesas Uno variants
    RAKWireless/RAK-nRF52-Arduino 0x239A WisBlock RAK4631, RAK4630
    Industruino/IndustruinoSAMD 0x2E78 Industruino D21G
    Heltec-Aaron-Lee/WiFi_Kit_series 0x303a (Espressif derivative) 25 Heltec boards
    PJRC Teensy package (https://www.pjrc.com/teensy/td_162/teensy-package-1.62.0.tar.zst) 0x16C0 10 Teensy boards × multiple per-mode PIDs

    Embedded firmware / runtime sources

    Source VID(s) Coverage
    adafruit/circuitpython 0x239A + community ~400 boards (ports/*/boards/*/mpconfigboard.mk)
    micropython/micropython 0xF055 + vendor ~200 boards (ports/*/boards/*/mpconfigboard.h)
    PaulStoffregen/cores 0x16C0 Teensy 3.x/4.x USB descriptors per mode
    ARMmbed/DAPLink 0x0D28 ~100+ HIC+target combos
    probe-rs/probe-rs (/targets) per-probe ~700 chip targets, ~20 debug-probe types
    particle-iot/particle-usb 0x2B04 ~15 Particle (Photon, Argon, Boron)
    Seeed-Studio/platform-seeedboards per-MCU ~40 Seeed boards

    TIER 3 — Bootloader / flashing-tool sources (hard-coded VID/PID tables)

    Tool Path VID/PID Coverage License
    esptool esptool/loader.py + esptool/targets/esp32*.py 0x303A × ~14 PIDs (USB-JTAG-Serial per ESP32 variant) GPL-2.0+
    picotool picoboot_connection/picoboot_connection.c 0x2E8A × ~6 PIDs (RP2040/2350 BOOTSEL + picoprobe + MicroPython) BSD-3-Clause
    BOSSA (arduino fork) n/a (relies on TTY enumeration; pairs in arduino-cores boards.txt) SAMD21/SAMD51 SAM-BA BSD-3-Clause
    OpenOCD tcl/interface/* + src/jtag/drivers/cmsis_dap_usb_bulk.c ~150 pairs across ~70 interface cfgs GPL-2.0+
    pyOCD pyocd/probe/pydapaccess/interface/common.py (KNOWN_CMSIS_DAP_IDS) ~30 (ARM, Atmel, Cypress, Keil, NXP, Vega, WCH) Apache-2.0
    probe-rs src/probe/{cmsisdap,stlink,jlink,wlink,ftdi,espusbjtag}/ ~25 (DAPLink, STLink, JLink, WCH-Link, FTDI, ESP USB-JTAG, BMP) MIT OR Apache-2.0
    dfu-util src/dfuse.c + src/quirks.c 0x0483:0xDF11 STM32 canonical + ~10 quirks GPL-2.0
    teensy_loader_cli teensy_loader_cli.c 0x16C0:{0x0478,0x0477,0x0483} GPL-3.0
    uf2families.json utils/uf2families.json ~80 MCU UF2 family IDs (use with vendor UF2 bootloader VIDs: Adafruit 0x239A, Espressif 0x239B, Arduino 0x2341, RPi 0x2E8A) MIT
    blackmagic-debug src/platforms/hosted/bmp_libusb.c ~16 (BMP 0x1D50:0x6018, ST-Link, JLink, WCH-Link, FTDI variants, Olimex) GPL-3.0+
    avrdude src/avrdude.conf.in ~50 programmer pairs (Atmel ISP/JTAG, FTDI, USBasp, USBtiny, Microchip jtag3, Arduino) GPL-2.0+
    ARMmbed/mbed-os-tools src/mbed_os_tools/detect/platform_database.py 1 VID × ~150 board IDs (DAPLink boards under 0x0D28) Apache-2.0
    arduino-cli + serial-discovery no central table — uses per-platform boards.txt aggregates all installed Arduino cores AGPL-3.0
    SEGGER 99-jlink.rules (mirror: 1847123212/jlink-5.10) udev rules 0x1366 + all J-Link PIDs SEGGER proprietary
    stlink-org/stlink config/udev/rules.d/49-stlinkv*.rules 0x0483 + STLink V1/V2/V3 PIDs (0x3744/0x3748/0x374B/0x374D/0x374E/0x374F) BSD-3-Clause
    Micronucleus (Digispark) 0x16D0:0x0753 single-pair GPL-2.0
    adafruit/Adafruit_nRF52_nrfutil 0x239A nRF52 bootloader PIDs Adafruit nRF52 family MIT

    TIER 4 — System-level USB databases (aggregator backbones)

    DB URL Scope Coverage License
    Linux USB ID Repository (canonical) http://www.linux-usb.org/usb.ids per-product (vendor + device tree + class/HID/audio) ~3,700 vendors / ~22,000 products GPL-2.0 OR BSD-3-Clause (dual)
    vcrhonek/hwdata (Fedora upstream) git mirrors linux-usb.org 1:1 with tagged releases same coverage GPL-2.0+ / BSD-3
    Debian usbutils embedded usb.ids https://salsa.debian.org/debian/usbutils per-product mirrors linux-usb.org (stale-by-release) GPL-2.0+
    woodruffw/usb-ids.rs crates.io/crates/usb-ids per-product Rust crate (date-stamped versions) mirrors linux-usb.org MIT
    systemd hwdb https://github.com/systemd/systemd/blob/main/hwdb.d/20-usb-vendor-model.hwdb per-product (mirrored from usb.ids) ~47,929 entries LGPL-2.1+
    Linux kernel USB quirks https://github.com/torvalds/linux/blob/master/drivers/usb/core/quirks.c device-quirk (VID:PID → behavioral flags) ~190 entries (+ 1000+ in unusual_devs.h, scattered driver tables) GPL-2.0
    Linux modules.alias /lib/modules/$(uname -r)/modules.alias (generated by depmod) per-product driver-binding records tens of thousands per kernel build GPL-2.0
    USB-IF vendor_ids.pdf https://www.usb.org/sites/default/files/vendor_ids051920_0.pdf vendor-only (authoritative) ~6,000 companies USB-IF (factual data)
    usb-ids.gowdy.us HTTPS browser/raw per-product (mirror of upstream by same maintainer) mirrors linux-usb.org GPL/BSD dual
    the-sz.com USB ID DB https://the-sz.com/products/usbid/index.php per-product (community scrape) undisclosed not declared
    Wireshark bundled USB IDs https://gitlab.com/wireshark/wireshark/-/blob/master/epan/dissectors/usb.c per-product (regenerated from usb.ids + libgphoto2) mirrors upstream GPL-2.0+
    per1234/zzInoVIDPID https://github.com/per1234/zzInoVIDPID USB-serial chip mapping (FTDI, CP210x, CH340, PL2303 → "might be any of these boards") ~50 chip variants Public-domain-ish
    NirSoft USBDeview https://www.nirsoft.net/utils/usb_devices_view.html tool (consumes usb.ids — not its own DB) n/a closed
    Windows HKLM\SYSTEM\CurrentControlSet\Enum\USB in-registry, via PnPUtil/Get-PnpDevice per-product (host-local only) machine-local n/a
    macOS system_profiler -json SPUSBDataType /usr/sbin/system_profiler per-product (host-local; Apple's IORegistry table is private) host-local n/a

    Confirmed NEGATIVE results (no per-board PID registry exists publicly)

    Verified across vendor GitHub orgs + corporate sites:

    • STMicroelectronics, NXP, Microchip, Nordic, Silicon Labs, Texas Instruments, Renesas, Cypress/Infineon, Ambiq, WCH/openwch, DFRobot, Pimoroni, SparkFun, Atmel: NO public per-board PID registry. VIDs reused with single SDK-default PID across all examples, OR customer-assigned PIDs privately by email.
    • Silicon Labs: has a request form (silabs.com/interface/request-product-id) but no public manifest.
    • Nordic: explicitly states no customer PID assignment process.
    • NXP MCUXpresso / Microchip Harmony / TI SimpleLink / Renesas e2 / Cypress PSoC: per-example USB descriptors only (e.g., NXP 0x1FC9:0x00A2 reused across all examples).
    • IEEE OUI database (https://standards-oui.ieee.org/oui/oui.txt): covers Ethernet MAC OUIs — NOT USB VIDs. Listed for completeness so this doesn't get re-investigated.

    VID/PID ambiguities to flag in downstream consumers

    VID Issue
    0x0403 FTDI Massive counterfeit FT232 ecosystem; FTDI historically bricked clones via PID rewrite. Some clones re-VID to 0x1A86 (WCH CH340G masquerading). Treat with suspicion.
    0x10C4 SiLabs CP210x Many ESP32/STM32 board houses use legitimate SiLabs USB-UART; some rebranders ship rewritten iManufacturer strings. VID real; product string unreliable.
    0x2341 Arduino SA vs 0x2A03 Arduino.org Both legitimate (post-split). Counterfeit Unos commonly use 0x1A86:7523 (CH340G) and present "USB-Serial CH340" — not Arduino at all.
    0x303A Espressif Shared VID; PID alone insufficient — must consult espressif/usb-pids to disambiguate vendor.
    0x2E8A Raspberry Pi Same — PID disambiguates 3rd-party board maker.
    0x1A86 WCH (QinHeng) Heavily cloned CH340/CH341/CH9102 with overlapping PIDs across product lines.
    0x0483 STMicroelectronics DFU bootloader PID 0xDF11 reused by countless 3rd-party STM32 boards that didn't apply for their own PID.
    0x16C0 V-USB shared (Objective Development) Explicitly licensed for sub-PID sharing — VID alone meaningless; consult obdev/v-usb/USB-IDs-for-free.txt.
    0x1209 pid.codes Same model — community-allocated PIDs under one VID.
    0x04B4 Cypress Post-Infineon acquisition; usb.ids still says "Cypress Semiconductor" — treat as Infineon.
    0x046D Logitech Acquired Saitek, Astro, Streamlabs — PIDs span multiple effective vendors.
    0x05AC Apple Most peripheral PIDs unreleased to public DBs; usb.ids coverage is partial.

    Ingestion priority for tools/sync_vendors.py

    Land in this order (each is an independent commit):

    1. Tier 1 official registries (6 sources, all PR-friendly, easily parseable): raspberrypi/usb-pid, espressif/usb-pids, pid.codes, openmoko-usb-oui, obdev/v-usb, creationid/creators.
    2. PlatformIO hwids registry — covers everything else as a tier-2 fallback (~1500 boards).
    3. Arduino-core ecosystem boards.txt — 22 cores total (catches boards PIO doesn't ship; especially earlephilhower/arduino-pico for its 11-VID partner-board coverage).
    4. CircuitPython / MicroPython port configs — catches Adafruit/MP-specific PIDs (~600 boards combined).
    5. Linux usb.ids via vcrhonek/hwdata — last-resort vendor-name fallback for any unmatched VID.
    6. Linux kernel quirks table — optional annotation layer for "known-weird" devices.

    Skip: Tier-4 SDK example defaults (NXP/Microchip/etc.) — they generate false-positive collisions across unrelated boards. Skip the-sz.com, NirSoft, DriverPack, etc. (opaque provenance, redundant with usb.ids).


    Updated acceptance criteria

    • tools/sync_vendors.py parses 22 Arduino-core boards.txt sources (the 7 originally listed + 15 newly catalogued).
    • Tier-1 PID registries: 6 sources (originally listed 2; now expanded to include pid.codes, openmoko-usb-oui, obdev/v-usb, creationid/creators).
    • Bootloader-tool tables ingested as supplementary layer: esptool, picotool, OpenOCD, pyOCD, probe-rs, BlackMagic, avrdude, mbed-os-tools, teensy_loader_cli, dfu-util quirks (~10 sources, all parseable).
    • Linux usb.ids ingested via woodruffw/usb-ids.rs (Rust-native) OR vcrhonek/hwdata (filesystem).
    • vendors/_meta.json documents 12 known VID ambiguities (FTDI clones, CH340 masquerade, Arduino split, etc.) so downstream pretty() can mark them with a confidence score.
    • Documented gaps: STM/NXP/Microchip/SiLabs/Nordic/TI/Renesas/Cypress/Ambiq/WCH have NO public per-board registry. Per-board PIDs for those vendors recoverable only via PlatformIO hwids or vendor-specific Arduino-core boards.txt.

    Original 9-source acceptance criterion is superseded — the real source count is ~50+ across all tiers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions