V-USB puts a USB stack inside an Atmel AVR without a USB controller
A Firmware-Only USB implementation for Atmel's AVR Microcontrollers
At a glance
- What is it?
- V-USB is a firmware-only USB driver for Atmel AVR microcontrollers, which lets a chip with no USB hardware act as a USB device by driving the data lines in software. The repository holds the driver source, six example projects, host and device libraries and the circuit notes, and it is distributed under three licence options, GPL v2, GPL v3 or a commercial licence.
- Who is it for?
- V-USB is worth using if you are building a USB device on a microcontroller that has no USB controller and you want a stack you can read and modify in assembly and C, because the driver is small, the examples are complete devices, and the integration is a directory copy rather than a dependency.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 59 days ago.
- What is it written in?
- Mainly Assembly, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Software USB on a chip with no USB peripheral
V-USB is described as a firmware-only USB driver for Atmel's AVR microcontrollers, and the entire idea is in that phrase. A microcontroller such as an ATtiny85 has no USB controller, and V-USB makes it act as a USB device anyway by implementing the protocol in firmware and driving the data lines directly. The reason anyone would do that is cost and part selection, because a chip with USB hardware is more expensive and larger than one without, and for a simple device such as a keyboard or a mouse the saving is worth the complexity. The project is hosted by Objective Development, and the upstream site is obdev.at/vusb/, which is where the device design information lives. The interesting engineering is in the driver itself, which is written in C with the timing-critical parts in assembly, and the repository's primary language is listed as Assembly for that reason.
The checkout is not the release package, and that trips people up
The README opens with a warning that is easy to skim past and costly to ignore. When you check out this repository, the resulting directory is not equivalent to the source code package which can be downloaded from obdev.at/vusb/. Some files in the source code package are generated by scripts when the package is created. On the other hand, the scripts which generate source files and the package are not contained in the package itself. So the two forms are complementary, the repository has the generators and the package has the generated output, and the Makefile encodes the difference. The distinction between a repository clone and a source package is made by the existence of make-files.sh scripts in various subdirectories, and the files target walks the tree and runs make-files.sh in each directory that has one. There is also a filesremove target that deletes the generated files again, and the clean target calls it, so a clean clone returns to its checked-in state. Readme.txt in the top level directory explains the files and directories in detail, and that is the file to read before you assume a missing file is a bug.
Adding the driver to a Makefile project
The integration is a copy and a list. Simply copy the entire usbdrv subdirectory into your project's firmware source code directory, then edit the firmware's Makefile and add the following object files to your binary:
usbdrv/usbdrv.o
usbdrv/usbdrvasm.o
usbdrv/oddebug.oThe three objects are the driver itself, the assembly part and the debug output component. Then you have to make sure that your Makefile contains rules to convert *.S and *.c to object files, since the driver ships both, and the README points at the Makefiles in the examples subdirectory for inspiration. That is the whole contract, and it is an old-fashioned one. There is no package manager, no configuration discovery and no dependency tree, which for a project of this age and this size is a feature rather than an omission, since the driver is a fixed set of files that either compiles or does not. The one thing you own is usbconfig.h, the configuration header, which is derived from a template and is where the driver is told about your hardware.
PlatformIO needs one detail most people miss
The PlatformIO route is described as the easiest way to use V-USB, and it is a folder copy, the usbdrv folder into the src directory of the project, which produces a layout like this:
project/
├── platformio.ini
└── src/
├── main.c
├── usbconfig.h
└── usbdrv/
├── usbdrv.c
├── usbdrv.h
├── usbdrvasm.S
├── usbdrvasm*.inc
├── oddebug.c
└── oddebug.hThe usbconfig.h is part of your project, derived from the template as usual. The detail that catches people is in platformio.ini, where you must make sure that .S files are preprocessed by the C preprocessor and then passed to the assembler, and that .inc and .asm files should not be touched, since they are included as needed. The minimal configuration for a bare metal ATtiny85 shows why, with the f_cpu set as a long constant so it also reaches usbdrvasm.S as a define, the -Isrc flag so that the driver sources find usbconfig.h, and a build_src_filter that keeps the IAR-syntax assembly file out of the build:
[env:attiny85]
platform = atmelavr
board = attiny85
board_build.f_cpu = 16500000L ; also reaches usbdrvasm.S as -DF_CPU=...
build_flags =
-Isrc ; explicit, so usbdrv/*.c find usbconfig.h
-Wall
; keep the IAR-syntax assembly file out of the build
build_src_filter =
+<*>
-<usbdrv/usbdrvasm.asm>Seven examples that are really the documentation
The examples directory is where the project teaches, and the set is a sensible progression through the USB device classes. There is drivertest, which is the bare driver test, custom-class, which is a device with a vendor-specific class, hid-custom-rq, which covers a HID device with a custom request, hid-data, which is a HID device that exchanges data, hid-mouse, which is a mouse, and usbtool, which is a host side tool. Each of those is a complete device rather than a snippet, so the fastest way to learn the API is to build one and read it. The repository also has a libs-host/ directory for code that runs on the computer side, a libs-device/ directory for code that runs on the device, a circuits/ directory for the hardware notes, a tests/ directory, and a v-usb.xcodeproj at the root, which is there for the macOS host tooling. The README for the examples directory is the entry point, and the top level Readme.txt is the file that explains how all of these fit together.
Three licence doors, and the choice is early
The licence arrangement is unusual and worth reading before you design a product. The Makefile header states the licence as GNU GPL v2, with a reference to License.txt, GNU GPL v3, or proprietary, with a reference to CommercialLicense.txt. That is three options, and the third is the one that matters commercially, since a USB stack that drives a data line in firmware ends up inside a product, and a GPL obligation on a shipped product is a commercial decision rather than a legal detail. The file names make the structure explicit, with License.txt and CommercialLicense.txt sitting alongside the sources, and the Objective Development copyright notice from 2012 at the top of the Makefile. The project is a commercial one with an open source core and a paid alternative, which is a common arrangement for embedded tooling, and the practical advice is to settle the licence before the board layout is fixed rather than after.
The build walks the tree instead of listing targets
The root Makefile is worth reading as an example of a build that handles a repository and a source package with one set of targets. The default target all builds everything that can be built except the tests, and the clean target removes all dependent files, and in a repository clone the derived source files are generated and deleted as well. The mechanism is the pair of unix and windows targets, which find every Makefile at least three directories deep and run the appropriate target in each directory, with the firmware directories getting a hex target and the rest getting the requested one. The windows variant uses a cross-make.sh helper to run the Makefile.windows files through a Windows toolchain, and the files and filesremove targets again walk the tree looking for make-files.sh scripts. The result is a build that is not a list of targets but a rule about the shape of the tree, which is why adding an example needs no edit to the root Makefile, and also why a build failure in one example stops the others, since the loop breaks on the first failure.
Editorial conclusion
V-USB is worth using if you are building a USB device on a microcontroller that has no USB controller and you want a stack you can read and modify in assembly and C, because the driver is small, the examples are complete devices, and the integration is a directory copy rather than a dependency. It is the wrong tool if the chip has USB hardware, since using the peripheral is simpler and faster than bit-banging the bus, and it is the wrong tool if your product cannot live with a GPL obligation, which is a decision the licence section forces early. Before you design a board around it, read the circuits/ directory for the hardware requirements, and check the usbconfig.h template, because that file is yours to fill in and it is where the driver is configured.
Frequently asked questions
What is V-USB and what is it for?
It is a firmware-only USB driver for Atmel's AVR microcontrollers, which lets a chip with no USB controller act as a USB device by implementing the protocol in firmware. It is aimed at people designing low-cost USB devices such as keyboards and mice.
How do I add V-USB to my project?
Copy the whole usbdrv subdirectory into your firmware source directory, then add usbdrv/usbdrv.o, usbdrv/usbdrvasm.o and usbdrv/oddebug.o to the object files in your binary, and make sure your Makefile has rules to convert *.S and *.c into object files. The usbconfig.h is yours, derived from the template.
Why does my PlatformIO build fail with V-USB?
In platformio.ini you must make sure that .S files are preprocessed by the C preprocessor and then passed to the assembler, while .inc and .asm files are left alone because they are included as needed. The example configuration also shows a build_src_filter that keeps the IAR-syntax assembly file out of the build.
Under which licence is V-USB available?
The Makefile header lists three options, GNU GPL v2 with the text in License.txt, GNU GPL v3, or proprietary with the text in CommercialLicense.txt. The repository metadata does not carry a standard licence identifier, so the licence files in the repository are the reference.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/obdev-v-usb)Was this useful?