{"id":51843424,"url":"https://github.com/xrip/ch32v003-hid-bootloader","last_synced_at":"2026-07-23T09:01:48.931Z","repository":{"id":369848915,"uuid":"1291825327","full_name":"xrip/ch32v003-hid-bootloader","owner":"xrip","description":"USB HID bootloader for CH32V003, flashable from the browser via WebHID","archived":false,"fork":false,"pushed_at":"2026-07-15T12:32:08.000Z","size":130,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-15T14:18:48.661Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://xrip.github.io/ch32v003-hid-bootloader/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xrip.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-07-07T05:52:28.000Z","updated_at":"2026-07-15T12:31:51.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/xrip/ch32v003-hid-bootloader","commit_stats":null,"previous_names":["xrip/ch32v003-hid-bootloader"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/xrip/ch32v003-hid-bootloader","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xrip%2Fch32v003-hid-bootloader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xrip%2Fch32v003-hid-bootloader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xrip%2Fch32v003-hid-bootloader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xrip%2Fch32v003-hid-bootloader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xrip","download_url":"https://codeload.github.com/xrip/ch32v003-hid-bootloader/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xrip%2Fch32v003-hid-bootloader/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35796817,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-23T02:00:06.683Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-07-23T09:01:48.119Z","updated_at":"2026-07-23T09:01:48.919Z","avatar_url":"https://github.com/xrip.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CH32V003 USB HID bootloader + flasher\n\n**[Flash it from your browser →](https://xrip.github.io/ch32v003-hid-bootloader/webhid-flasher.html)**\n(WebHID; Chrome, Edge, Opera. No install.)\n\nA small USB HID bootloader for the CH32V003. The device enumerates as a\nvendor HID device (VID `0x1209`, PID `0xBEEF`) and is flashed from a\nbrowser over WebHID, with no native host tooling required. Its USB\nproduct name is `CH32V`.\n\nThe CH32V003 has no hardware USB peripheral. The bootloader bit-bangs a\nlow-speed HID stack, which is small enough to live in the 1920-byte\nboot area. Flash data uses HID feature reports over control endpoint 0;\nthe required HID Interrupt IN endpoint is present but carries no data.\nThe board has a fixed 1.5 kΩ pull-up from D- to 3.3 V. On entry and\nbefore starting the user app, the bootloader drives D- low for a short\nUSB disconnect.\n\n## Building\n\nPrerequisites: CMake ≥ 3.20, Ninja, and the xPack RISC-V GCC toolchain\n(put its `bin/` on your `PATH`).\n\n```powershell\ncmake -S . -B build -G Ninja\ncmake --build build\n```\n\nThe build emits:\n\n- `bin/ch32v003_hid_bootloader.elf`\n- `bin/ch32v003_hid_bootloader.bin`\n\nIt fails if the binary exceeds the CH32V003 boot-area limit of 1920 bytes\n(the linker script enforces this).\n\n## Flashing from the host\n\nOpen `webhid-flasher.html` in a Chromium-based browser (Chrome, Edge,\nor Opera). The page accepts `.bin`, `.elf`, and `.uf2` files, converts\nthem client-side, and sends addressed 8-byte chunks over HID feature\nreports. The device enumerates as `1209:BEEF` — that's\nthe filter the WebHID page uses to find it.\n\nTo flash:\n\n1. Pick a firmware file.\n2. Click **Flash**.\n3. Plug in the CH32V003 (or reset it) — the page detects it and starts\n   flashing automatically.\n\nFirst time only: plug in the board *before* clicking Flash so your\nbrowser can show the one-time permission prompt. After that, the three\nsteps above are all you need — a reset is enough to start each new\nflash.\n\nFor detailed Windows-side diagnostics, use the dependency-free Python\ntool. It logs device identity, HID report sizes and IDs, every packet,\naddress, payload, result, Windows error, transfer time, and wait:\n\n```powershell\npython .\\hid-flasher.py --probe\npython .\\hid-flasher.py firmware.bin --dry-run\npython .\\hid-flasher.py firmware.bin\n```\n\nThe tool accepts `.bin`, `.elf`, and `.uf2`. Use `--base` for a BIN with\na non-default address, `--step` for one packet at a time, or\n`--limit-chunks N --no-reset` for a controlled partial-write test.\n\nOn power-up the bootloader waits for about five seconds. If no\nfirst write report arrives during that window it jumps straight to the\nuser application; once flashing starts it stays active and writes the\npayload into flash. When all pages are written, the flasher sends a\nreset command and the chip reboots into the newly-written user\napplication. If the first user-flash word is erased (`0xFFFFFFFF`), the\nbootloader stays active instead of starting empty flash.\n\n## Limitations\n\n- No readback verification.\n- No status or error report from the device.\n- If flashing does not start after reset, the bootloader jumps to the\n  user app after a fixed busy-loop timeout.\n- Device-side address validation is intentionally minimal; the WebHID\n  page validates CH32V003 flash ranges (`0x08000000`–`0x08004000`,\n  16 KB) before sending.\n\n## Size budget and optimizations\n\nThe bootloader fits in a **1920-byte BOOT area** on the CH32V003 (remapped\nto `0x00000000` on reset). The linker script enforces this: overflow\nfails the link. The current binary is **1804 / 1920 B (94 %)**.\n\nThe code is size-focused, but its identifiers remain descriptive.\n`-nostdlib` acts as a guardrail: a stray\n`int * int` would fail the link instead of silently pulling `__mulsi3`\n(~+36 B) into the image. The main size reductions are a shared descriptor\nlookup table, a 16-byte report buffer with word copies, aligned command-header\nreads, and the inlined `process_flash_report` handler. The build also\nforce-inlines `wait_for_flash`, writes the needed peripheral registers\ndirectly, and keeps `boot_firmware` as one stable handoff point under LTO.\n\nLibrary audit: zero libgcc/libc symbols. The rv003usb ISR is at its\nfeature floor — every optional macro is off and `--gc-sections` removes\nnothing.\n\n## Credits\n\nThe low-speed USB stack in `rv003usb/` is\n[rv003usb](https://github.com/cnlohr/rv003usb) by Charles Lohr (cnlohr).\n\n## License\n\n[MIT](LICENSE.txt). Copyright (c) 2026, xrip.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxrip%2Fch32v003-hid-bootloader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxrip%2Fch32v003-hid-bootloader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxrip%2Fch32v003-hid-bootloader/lists"}