USBtiny is a software implementation of the USB low-speed protocol for the Atmel ATtiny microcontrollers. Of course, it will also work on the ATmega s...
USBtiny is a software implementation of the USB low-speed protocol for the Atmel ATtiny microcontrollers. Of course, it will also work on the ATmega series. The software is written for an AVR clocked at 12 MHz. At this frequency, each bit on the USB bus takes 8 clock cycles, and with a lot of trickery, it is possible to decode and encode the USB waveforms by software. The USB driver needs approximately 1250 to 1350 bytes of flash space (excluding the optional identification strings), depending on the configuration and compiler version, and 46 bytes RAM (excluding stack space). The C interface consists of 3 to 5 functions, depending on the configuration.
USB uses two differential data signals, D+ and D-, which are normally complementary. However, the end of a packet is signalled by pulling both signals low. Data is not transmitted directly on the USB bus, it is NRZI encoded first. This means that a “0″ bit is encoded as a bit change, and a “1″ bit is encoded as no bit change. After 6 “1″ bits, “bit stuffing” takes place to force a change on the USB signal lines.
The software is interrupt driven: the start of a USB packet triggers an interrupt. The interrupt handler synchronizes with the sync byte, removes the NRZI encoding and bit stuffing, and stores the packed in one of the two RAM buffers. Two buffers are used so that the next packet can be received while the current one is being processed. Depending on the packet type, a reply packed may be sent back immediately in the interrupt handler.
The rest of the USB driver is written in C. A usb_poll() function must to be called periodically to poll for incoming packets. Only a single endpoint is supported at the moment. Standard control requests are directly handled by the USB driver. Other SETUP requests are forwarded to a user-supplied function usb_setup(). Support for large replies and OUT control requests is optional, see usbtiny.h.
To use the USB driver in your own application, you need to configure the macros in usbtiny.h, and provide a function usb_setup() to handle SETUP control packets. Optionally, you need to provide the functions usb_in() and usb_out(). Your code needs to call the initialization function usb_init() at program startup, and usb_poll() at regular intervals. The AVR device type and the upload command should be configured at the top of the Makefile.