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
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
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"},
...
]
}
.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).
_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.
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
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.
Goal
Populate the
vendorsorphan branch with upstream-curated vendor PID allocation registries — the tier-1+2 sources fbuild'sonline-dataaggregator (v1) was designed to ingest, but never did because the curation pipeline outgrew "a few scripts in one workflow." Perdesign.md, fastled/boards is the v2 home for this data.Today:
vendorscarries only README.md + _meta.json (placeholder). Nosync-vendors.ymlworkflow exists onmain. Notools/sync_vendors.pyexists.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
vendorsbranch data, not re-do the upstream fetches.Upstream sources to ingest
Tier 1 — authoritative PID allocation registries (gold standard)
0x2E8Araspberrypi/usb-pid→Readme.md0x303Aespressif/usb-pids→allocated-pids.txt+allocated-pids-espressif-devboards.txtVVVV: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)arduino/ArduinoCore-avr→boards.txtarduino/ArduinoCore-samd→boards.txtespressif/arduino-esp32→boards.txtadafruit/Adafruit_nRF52_Arduino→boards.txtSiliconLabs/arduino→boards.txtstm32duino/Arduino_Core_STM32→boards.txtTier 3-4 — community / archived / single-pair
NordicSemiconductor/nrf-udev→71-nrf.rulesNordicSemiconductor/nrf-device-setup-js(archived 2022-01)Known gaps (no public registry — flag in
_meta.jsonprovenance)energia/Energiaunmaintained).stm32duinois community-run.See fbuild#722 for the full per-vendor breakdown of which sub-issue covers which source.
Proposed implementation
tools/sync_vendors.py(onmain) — fetcher + parser per source, modeled on the existingtools/sync_*.pypattern. Each source produces avendors/<vendor>.jsonwith 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"}, ... ] }.github/workflows/sync-vendors.yml(onmain) — nightly cron +workflow_dispatch, runstools/sync_vendors.py, then publishes the output to thevendorsorphan branch viatools/git_publish.py(force-with-lease, history pruned to ~200 commits — same machinery as the other orphan-branch workflows)._meta.jsonon thevendorsbranch — 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.build_usb_ids.py(already onmain) — extend to foldvendors/*.jsoninto the aggregate so thesitebranch's SQLite carries per-board PID resolution.Acceptance criteria
tools/sync_vendors.pyparses all 7 Arduino-core sources + 2 tier-1 PID registries + Nordic udev rules..github/workflows/sync-vendors.ymlruns nightly + onworkflow_dispatch, publishes tovendorsbranch.vendors/_meta.jsonlists every source with its commit SHA + fetch timestamp; known-gap vendors documented.build_usb_ids.pyingests the per-board data; thesitebranch's SQLitevidpidtable returns "Pico CircuitPython" for2e8a000b(not just "Pico SDK CDC UART").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)
design.md: the curation pipeline outgrew fbuild'sonline-datav1 — the explicit purpose of this repo is to be the v2 aggregator.vendorsorphan branch is already set up and waiting for data.sitebranch) need the same data and can read directly from this repo without depending on fbuild.Downstream coordination
Once this lands, FastLED/fbuild#722 closes — fbuild's
online-dataconsumer simply readsvendors/*.jsonfrom 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.